class EM::Hiredis::Lock
Cross-process re-entrant lock, backed by redis
Public Class Methods
new(redis, key, timeout)
click to toggle source
# File lib/em-hiredis/lock.rb, line 15 def initialize(redis, key, timeout) unless timeout.kind_of?(Fixnum) && timeout >= 1 raise "Timeout must be an integer and >= 1s" end @redis, @key, @timeout = redis, key, timeout @token = SecureRandom.hex end
Public Instance Methods
acquire()
click to toggle source
Acquire the lock
This is a re-entrant lock, re-acquiring will succeed and extend the timeout
Returns a deferrable which either succeeds if the lock can be acquired, or fails if it cannot.
# File lib/em-hiredis/lock.rb, line 28 def acquire df = EM::DefaultDeferrable.new @redis.lock_acquire([@key], [@token, @timeout]).callback { |success| if (success) EM::Hiredis.logger.debug "#{to_s} acquired" EM.cancel_timer(@expire_timer) if @expire_timer @expire_timer = EM.add_timer(@timeout - 1) { EM::Hiredis.logger.debug "#{to_s} Expires in 1s" @onexpire.call if @onexpire } df.succeed else EM::Hiredis.logger.debug "#{to_s} failed to acquire" df.fail("Lock is not available") end }.errback { |e| EM::Hiredis.logger.error "#{to_s} Error acquiring lock #{e}" df.fail(e) } df end
clear()
click to toggle source
This should not be used in normal operation. Force clear without regard to who owns the lock.
# File lib/em-hiredis/lock.rb, line 76 def clear EM::Hiredis.logger.warn "#{to_s} Force clearing lock (unsafe)" EM.cancel_timer(@expire_timer) if @expire_timer @redis.del(@key) end
onexpire(&blk)
click to toggle source
Register a callback which will be called 1s before the lock expires This is an informational callback, there is no hard guarantee on the timing of its invocation because the callback firing and lock key expiry are handled by different clocks (the client process and redis server respectively)
# File lib/em-hiredis/lock.rb, line 13 def onexpire(&blk); @onexpire = blk; end
to_s()
click to toggle source
# File lib/em-hiredis/lock.rb, line 83 def to_s "[lock #{@key}]" end
unlock()
click to toggle source
Release the lock
Returns a deferrable
# File lib/em-hiredis/lock.rb, line 55 def unlock EM.cancel_timer(@expire_timer) if @expire_timer df = EM::DefaultDeferrable.new @redis.lock_release([@key], [@token]).callback { |keys_removed| if keys_removed > 0 EM::Hiredis.logger.debug "#{to_s} released" df.succeed else EM::Hiredis.logger.debug "#{to_s} could not release, not held" df.fail("Cannot release a lock we do not hold") end }.errback { |e| EM::Hiredis.logger.error "#{to_s} Error releasing lock #{e}" df.fail(e) } df end