Class: RedisExpLock
- Inherits:
-
Object
- Object
- RedisExpLock
- Defined in:
- lib/redis_exp_lock.rb,
lib/redis_exp_lock/version.rb
Defined Under Namespace
Classes: AlreadyAcquiredLockError, TooManyLockAttemptsError
Constant Summary collapse
- LUA =
{ # Deletes keys if they equal the given values :delequal => """ local deleted = 0 if redis.call('GET', KEYS[1]) == ARGV[1] then return redis.call('DEL', KEYS[1]) end return 0 """, }
- VERSION =
'0.1.1'
Instance Attribute Summary collapse
-
#expiry ⇒ Object
readonly
Returns the value of attribute expiry.
-
#lock_key ⇒ Object
readonly
Returns the value of attribute lock_key.
-
#lock_uuid ⇒ Object
readonly
Returns the value of attribute lock_uuid.
-
#redis ⇒ Object
readonly
Returns the value of attribute redis.
-
#retries ⇒ Object
readonly
Returns the value of attribute retries.
-
#retry_interval ⇒ Object
readonly
Returns the value of attribute retry_interval.
Instance Method Summary collapse
-
#initialize(lock_key, opts) ⇒ RedisExpLock
constructor
A new instance of RedisExpLock.
- #key_locked? ⇒ Boolean
- #key_owned? ⇒ Boolean
- #lock ⇒ Object
- #locked? ⇒ Boolean
- #synchronize(&crit_sec) ⇒ Object
-
#try_lock ⇒ Object
Attempt to acquire the lock, returning true if the lock was succesfully acquired, and false if not.
- #unlock ⇒ Object
Constructor Details
#initialize(lock_key, opts) ⇒ RedisExpLock
Returns a new instance of RedisExpLock.
22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
# File 'lib/redis_exp_lock.rb', line 22 def initialize(lock_key, opts) defaults = { :expiry => nil, # in seconds :retries => 0, :retry_interval => 0.01, # in seconds } opts = {}.merge(defaults).merge(opts) @lock_key = lock_key.to_s raise ArgumentError.new('Invalid lock key') unless @lock_key.size > 0 @lock_uuid = nil @redis = opts[:redis] @shavaluator = Shavaluator.new(:redis => @redis) @shavaluator.add(LUA) @expiry = opts[:expiry] @retries = opts[:retries] @retry_interval = opts[:retry_interval] end |
Instance Attribute Details
#expiry ⇒ Object (readonly)
Returns the value of attribute expiry.
20 21 22 |
# File 'lib/redis_exp_lock.rb', line 20 def expiry @expiry end |
#lock_key ⇒ Object (readonly)
Returns the value of attribute lock_key.
20 21 22 |
# File 'lib/redis_exp_lock.rb', line 20 def lock_key @lock_key end |
#lock_uuid ⇒ Object (readonly)
Returns the value of attribute lock_uuid.
20 21 22 |
# File 'lib/redis_exp_lock.rb', line 20 def lock_uuid @lock_uuid end |
#redis ⇒ Object (readonly)
Returns the value of attribute redis.
20 21 22 |
# File 'lib/redis_exp_lock.rb', line 20 def redis @redis end |
#retries ⇒ Object (readonly)
Returns the value of attribute retries.
20 21 22 |
# File 'lib/redis_exp_lock.rb', line 20 def retries @retries end |
#retry_interval ⇒ Object (readonly)
Returns the value of attribute retry_interval.
20 21 22 |
# File 'lib/redis_exp_lock.rb', line 20 def retry_interval @retry_interval end |
Instance Method Details
#key_locked? ⇒ Boolean
47 48 49 |
# File 'lib/redis_exp_lock.rb', line 47 def key_locked? @redis.exists(@lock_key) end |
#key_owned? ⇒ Boolean
51 52 53 |
# File 'lib/redis_exp_lock.rb', line 51 def key_owned? !@lock_uuid.nil? && @lock_uuid == @redis.get(@lock_key) end |
#lock ⇒ Object
74 75 76 77 78 79 80 81 82 |
# File 'lib/redis_exp_lock.rb', line 74 def lock attempts = 0 while attempts <= @retries attempts += 1 return attempts if try_lock sleep @retry_interval end raise TooManyLockAttemptsError end |
#locked? ⇒ Boolean
43 44 45 |
# File 'lib/redis_exp_lock.rb', line 43 def locked? !@lock_uuid.nil? end |
#synchronize(&crit_sec) ⇒ Object
91 92 93 94 95 |
# File 'lib/redis_exp_lock.rb', line 91 def synchronize(&crit_sec) attempts = lock crit_sec.call attempts unlock end |
#try_lock ⇒ Object
Attempt to acquire the lock, returning true if the lock was succesfully acquired, and false if not.
57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 |
# File 'lib/redis_exp_lock.rb', line 57 def try_lock raise AlreadyAcquiredLockError if locked? uuid = SecureRandom.uuid set_opts = { :nx => true } set_opts[:px] = Integer(@expiry * 1000) if @expiry if @redis.set(@lock_key, uuid, set_opts) @lock_uuid = uuid true else false end end |
#unlock ⇒ Object
84 85 86 87 88 89 |
# File 'lib/redis_exp_lock.rb', line 84 def unlock return false unless locked? was_locked = @shavaluator.exec(:delequal, :keys => [@lock_key], :argv => [@lock_uuid]) == 1 @lock_uuid = nil was_locked end |