Class: Redis::Lock
- Inherits:
-
Object
- Object
- Redis::Lock
- Defined in:
- lib/redis-lock.rb,
lib/redis-lock/version.rb
Defined Under Namespace
Classes: AcquireLockTimeOut
Constant Summary collapse
- UNLOCK_LUA_SCRIPT =
"if redis.call('get',KEYS[1])==ARGV[1] then redis.call('del',KEYS[1]) end"
- VERSION =
"0.1.1"
Instance Attribute Summary collapse
-
#key ⇒ Object
readonly
Returns the value of attribute key.
-
#redis ⇒ Object
readonly
Returns the value of attribute redis.
Instance Method Summary collapse
-
#initialize(redis, key, options = {}) ⇒ Lock
constructor
A new instance of Lock.
-
#lock(acquire_timeout = 10, &block) ⇒ Object
Acquire the lock.
-
#locked? ⇒ Boolean
Boolean that is true if the lock is currently held by any process.
-
#locked_by_me?(force_remote = false) ⇒ Boolean
Determines whether or not the lock is held by this instance.
-
#unlock(force_remote = false) ⇒ Object
Releases the lock if it is held by this instance.
Constructor Details
#initialize(redis, key, options = {}) ⇒ Lock
Returns a new instance of Lock.
20 21 22 23 24 25 26 27 28 29 |
# File 'lib/redis-lock.rb', line 20 def initialize(redis, key, = {}) @redis = redis @key = "lock:#{key}" @auto_release_time = [:auto_release_time] || 30 @base_sleep_in_secs = ([:base_sleep] || 100) / 1000.0 # Unique token set as the redis value of @key when locked by this instance @instance_name = SecureRandom.hex # If lock was called and unlock has not yet been called, this is set to the time the lock was acquired @time_locked = nil end |
Instance Attribute Details
#key ⇒ Object (readonly)
Returns the value of attribute key.
8 9 10 |
# File 'lib/redis-lock.rb', line 8 def key @key end |
#redis ⇒ Object (readonly)
Returns the value of attribute redis.
7 8 9 |
# File 'lib/redis-lock.rb', line 7 def redis @redis end |
Instance Method Details
#lock(acquire_timeout = 10, &block) ⇒ Object
Acquire the lock. If a block is provided, the lock is acquired before yielding to the block and released once the block is returned.
34 35 36 37 38 39 40 41 42 43 |
# File 'lib/redis-lock.rb', line 34 def lock(acquire_timeout = 10, &block) raise AcquireLockTimeOut.new unless attempt_lock(acquire_timeout) if block begin yield(self) ensure unlock end end end |
#locked? ⇒ Boolean
Returns Boolean that is true if the lock is currently held by any process.
59 60 61 |
# File 'lib/redis-lock.rb', line 59 def locked? return !@redis.get(@key).nil? end |
#locked_by_me?(force_remote = false) ⇒ Boolean
Determines whether or not the lock is held by this instance. By default, this method relies on the expiration time of the key as a performance optimization when possible. If this is undesirable for some reason, set force_remote to true.
68 69 70 71 72 73 74 75 76 77 78 |
# File 'lib/redis-lock.rb', line 68 def locked_by_me?(force_remote = false) if @time_locked if force_remote return @redis.get(@key) == @instance_name end if Time.now < @time_locked + @auto_release_time return true end end return false end |
#unlock(force_remote = false) ⇒ Object
Releases the lock if it is held by this instance. By default, this method relies on the expiration time of the key as a performance optimization when possible. If this is undesirable for some reason, set force_remote to true.
48 49 50 51 52 53 54 55 56 |
# File 'lib/redis-lock.rb', line 48 def unlock(force_remote = false) # unlock is a no-op if we never called lock if @time_locked if Time.now < @time_locked + @auto_release_time || force_remote @redis.eval(UNLOCK_LUA_SCRIPT, [@key], [@instance_name]) end @time_locked = nil end end |