Class: Sqeduler::RedisLock
- Inherits:
-
Object
- Object
- Sqeduler::RedisLock
- Includes:
- RedisScripts
- Defined in:
- lib/sqeduler/redis_lock.rb
Overview
Uses eval_sha to execute server-side scripts on redis. Avoids some of the potentially racey and brittle dependencies on Time-based redis locks in other locking libraries.
Direct Known Subclasses
Defined Under Namespace
Classes: LockTimeoutError
Constant Summary collapse
- SLEEP_TIME =
0.1
Instance Attribute Summary collapse
-
#key ⇒ Object
readonly
Returns the value of attribute key.
-
#timeout ⇒ Object
readonly
Returns the value of attribute timeout.
Class Method Summary collapse
Instance Method Summary collapse
- #expiration_milliseconds ⇒ Object
-
#initialize(key, options = {}) ⇒ RedisLock
constructor
A new instance of RedisLock.
- #lock ⇒ Object
- #locked? ⇒ Boolean
- #refresh ⇒ Object
- #unlock ⇒ Object
Methods included from RedisScripts
Constructor Details
#initialize(key, options = {}) ⇒ RedisLock
Returns a new instance of RedisLock.
13 14 15 16 17 18 |
# File 'lib/sqeduler/redis_lock.rb', line 13 def initialize(key, = {}) @key = key @expiration = [:expiration] fail ArgumentError, "Expiration must be provided!" unless @expiration @timeout = [:timeout] || 5 end |
Instance Attribute Details
#key ⇒ Object (readonly)
Returns the value of attribute key.
11 12 13 |
# File 'lib/sqeduler/redis_lock.rb', line 11 def key @key end |
#timeout ⇒ Object (readonly)
Returns the value of attribute timeout.
11 12 13 |
# File 'lib/sqeduler/redis_lock.rb', line 11 def timeout @timeout end |
Class Method Details
.with_lock(key, options) ⇒ Object
66 67 68 69 70 71 72 73 74 75 76 77 |
# File 'lib/sqeduler/redis_lock.rb', line 66 def self.with_lock(key, ) fail "Block is required" unless block_given? mutex = new(key, ) unless mutex.lock fail LockTimeoutError, "Timed out trying to get #{key} lock. Exceeded #{mutex.timeout} sec" end begin yield ensure mutex.unlock end end |
Instance Method Details
#expiration_milliseconds ⇒ Object
79 80 81 82 |
# File 'lib/sqeduler/redis_lock.rb', line 79 def expiration_milliseconds # expiration needs to be an integer @expiration ? (@expiration * 1000).to_i : 0 end |
#lock ⇒ Object
20 21 22 23 24 25 26 27 28 29 30 31 32 |
# File 'lib/sqeduler/redis_lock.rb', line 20 def lock Service.logger.info( "Try to acquire lock with #{key}, expiration: #{@expiration} sec, timeout: #{timeout} sec" ) return true if locked? if poll_for_lock Service.logger.info "Acquired lock #{key} with value #{lock_value}" true else Service.logger.info "Failed to acquire lock #{key} with value #{lock_value}" false end end |
#locked? ⇒ Boolean
54 55 56 57 58 59 60 61 62 63 64 |
# File 'lib/sqeduler/redis_lock.rb', line 54 def locked? redis_pool.with do |redis| if redis.get(key) == lock_value Service.logger.info "Lock #{key} with value #{lock_value} is valid" true else Service.logger.info "Lock #{key} with value #{lock_value} has expired or is not present" false end end end |