Module: Redis::Lock
- Included in:
- Redis
- Defined in:
- lib/redis/lock.rb,
lib/redis-lock/version.rb
Constant Summary collapse
- VERSION =
"0.2.0"
Instance Method Summary collapse
-
#lock(key, timeout = 60, max_attempts = 100) ⇒ Object
Lock a given key.
-
#lock_for_update(key, timeout = 60, max_attempts = 100) ⇒ Object
Lock a given key for updating.
-
#unlock(key) ⇒ Object
Unlock a previously locked key if it has not expired and the current process/thread was the one that locked it.
Instance Method Details
#lock(key, timeout = 60, max_attempts = 100) ⇒ Object
Lock a given key. Optionally takes a timeout and max number of attempts to lock the key before giving up.
Example:
$redis.lock(‘beers_on_the_wall’, 10, 100)
33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 |
# File 'lib/redis/lock.rb', line 33 def lock(key, timeout = 60, max_attempts = 100) current_lock_key = lock_key(key) expiration_value = lock_expiration(timeout) attempt_counter = 0 while attempt_counter < max_attempts if self.setnx(current_lock_key, expiration_value) return true else current_lock = self.get(current_lock_key) if (current_lock.to_s.split('-').first.to_i) < Time.now.to_i compare_value = self.getset(current_lock_key, expiration_value) return true if compare_value == current_lock end end attempt_counter += 1 sleep 1 if attempt_counter < max_attempts end raise RedisLockException.new("Unable to acquire lock for #{key}.") end |
#lock_for_update(key, timeout = 60, max_attempts = 100) ⇒ Object
Lock a given key for updating
Example:
$redis = Redis.new lock_for_update(‘beers_on_the_wall’, 20, 1000) do
$redis.decr('beers_on_the_wall')
end
15 16 17 18 19 20 21 22 23 24 25 |
# File 'lib/redis/lock.rb', line 15 def lock_for_update(key, timeout = 60, max_attempts = 100) if self.lock(key, timeout, max_attempts) response = nil begin response = yield if block_given? ensure self.unlock(key) end return response end end |
#unlock(key) ⇒ Object
Unlock a previously locked key if it has not expired and the current process/thread was the one that locked it.
Example:
$redis.unlock(‘beers_on_the_wall’)
61 62 63 64 65 66 67 68 69 70 71 72 |
# File 'lib/redis/lock.rb', line 61 def unlock(key) current_lock_key = lock_key(key) lock_value = self.get(current_lock_key) return true unless lock_value lock_timeout, lock_process, lock_thread = lock_value.split('-') if (lock_timeout.to_i > Time.now.to_i) && (lock_process.to_i == Process.pid) && lock_thread.to_i == Thread.current.object_id self.del(current_lock_key) return true else return false end end |