Class: Sqeduler::RedisLock
- Inherits:
-
Object
- Object
- Sqeduler::RedisLock
show all
- 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.
Defined Under Namespace
Classes: LockTimeoutError
Constant Summary
collapse
- SLEEP_TIME =
0.1
Instance Attribute Summary collapse
Class Method Summary
collapse
Instance Method Summary
collapse
#refresh_lock, #release_lock
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, options = {})
@key = key
@expiration = options[:expiration]
fail ArgumentError, "Expiration must be provided!" unless @expiration
@timeout = options[:timeout] || 5
end
|
Instance Attribute Details
#key ⇒ Object
Returns the value of attribute key.
11
12
13
|
# File 'lib/sqeduler/redis_lock.rb', line 11
def key
@key
end
|
#timeout ⇒ Object
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, options)
fail "Block is required" unless block_given?
mutex = new(key, options)
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 ? (@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
|
#refresh ⇒ Object
44
45
46
47
48
49
50
51
52
|
# File 'lib/sqeduler/redis_lock.rb', line 44
def refresh
if refresh_lock
Service.logger.info "Refreshed lock #{key} with value #{lock_value}"
true
else
Service.logger.info "Cannot refresh lock #{key} with value #{lock_value}"
false
end
end
|
#unlock ⇒ Object
34
35
36
37
38
39
40
41
42
|
# File 'lib/sqeduler/redis_lock.rb', line 34
def unlock
if release_lock
Service.logger.info "Released lock #{key} with value #{lock_value}"
true
else
Service.logger.info "Cannot release lock #{key} with value #{lock_value}"
false
end
end
|