# class EM::Hiredis::PersistentLock

A lock that automatically re-acquires a lock before it loses it

The lock is configured with the following two parameters

:lock_timeout - Specifies how long each lock is acquired for. Setting

    this low means that locks need to be re-acquired very often, but a long
    timout means that a process that fails without cleaning up after itself
    (i.e. without releasing it's underlying lock) will block the anther
    process from picking up this lock
    replaced for a long while

:retry_interval - Specifies how frequently to retry acquiring the lock in

    the case that the lock is held by another process, or there's an error
    communicating with redis

### Public Class Methods

new(redis, key, options = {}) click to toggle source

    # File lib/em-hiredis/persistent_lock.rb, line 20
    def initialize(redis, key, options = {})
      @redis, @key = redis, key
      @timeout = options[:lock_timeout] || 100
      @retry_timeout = options[:retry_interval] || 60

      @lock = EM::Hiredis::Lock.new(redis, key, @timeout)
      @locked = false
      EM.next_tick {
        @running = true
        acquire
      }
    end

### Public Instance Methods

acquire() click to toggle source

Acquire the lock (called automatically by initialize)

    # File lib/em-hiredis/persistent_lock.rb, line 34
    def acquire
      return unless @running

      @lock.acquire.callback {
        if !@locked
          @onlocked.call if @onlocked
          @locked = true
        end

        # Re-acquire lock near the end of the period
        @extend_timer = EM.add_timer(@timeout.to_f * 2 / 3) {
          acquire()
        }
      }.errback { |e|
        if @locked
          # We were previously locked
          @onunlocked.call if @onunlocked
          @locked = false
        end

        if e.kind_of?(EM::Hiredis::RedisError)
          err = e.redis_error
          EM::Hiredis.logger.warn "Unexpected error acquiring #{@lock} #{err}"
        end

        @retry_timer = EM.add_timer(@retry_timeout) {
          acquire() unless @locked
        }
      }
    end

locked?() click to toggle source

    # File lib/em-hiredis/persistent_lock.rb, line 77
    def locked?
      @locked
    end

onlocked(&blk) click to toggle source

    # File lib/em-hiredis/persistent_lock.rb, line 17
    def onlocked(&blk); @onlocked = blk; self; end

onunlocked(&blk) click to toggle source

    # File lib/em-hiredis/persistent_lock.rb, line 18
    def onunlocked(&blk); @onunlocked = blk; self; end

stop() click to toggle source

    # File lib/em-hiredis/persistent_lock.rb, line 65
    def stop
      @running = false
      EM.cancel_timer(@extend_timer) if @extend_timer
      EM.cancel_timer(@retry_timer) if @retry_timer
      if @locked
        # We were previously locked
        @onunlocked.call if @onunlocked
        @locked = false
      end
      @lock.unlock
    end