Class: Redlock::Client
- Inherits:
-
Object
- Object
- Redlock::Client
- Defined in:
- lib/redlock/client.rb,
lib/redlock/testing.rb
Defined Under Namespace
Classes: RedisInstance
Constant Summary collapse
- DEFAULT_REDIS_URLS =
['redis://localhost:6379']
- DEFAULT_REDIS_TIMEOUT =
0.1
- DEFAULT_RETRY_COUNT =
3
- DEFAULT_RETRY_DELAY =
200
- CLOCK_DRIFT_FACTOR =
0.01
Instance Attribute Summary collapse
-
#testing_mode ⇒ Object
writeonly
Sets the attribute testing_mode.
Instance Method Summary collapse
-
#initialize(servers = DEFAULT_REDIS_URLS, options = {}) ⇒ Client
constructor
Create a distributed lock manager implementing redlock algorithm.
-
#lock(resource, ttl, options = {}, &block) ⇒ Object
Locks a resource for a given time.
-
#lock!(*args) ⇒ Object
Locks a resource, executing the received block only after successfully acquiring the lock, and returning its return value as a result.
- #try_lock_instances(resource, ttl, options) ⇒ Object
- #try_lock_instances_without_testing ⇒ Object
-
#unlock(lock_info) ⇒ Object
Unlocks a resource.
-
#unlock_without_testing ⇒ Object
Unlocks a resource.
Constructor Details
#initialize(servers = DEFAULT_REDIS_URLS, options = {}) ⇒ Client
Create a distributed lock manager implementing redlock algorithm. Params:
servers
-
The array of redis connection URLs or Redis connection instances. Or a mix of both.
options
-
You can override the default value for ‘retry_count` and `retry_delay`.
* `retry_count` being how many times it'll try to lock a resource (default: 3)
* `retry_delay` being how many ms to sleep before try to lock again (default: 200)
* `redis_timeout` being how the Redis timeout will be set in seconds (default: 0.1)
19 20 21 22 23 24 25 26 27 28 29 30 31 |
# File 'lib/redlock/client.rb', line 19 def initialize(servers = DEFAULT_REDIS_URLS, = {}) redis_timeout = [:redis_timeout] || DEFAULT_REDIS_TIMEOUT @servers = servers.map do |server| if server.is_a?(String) RedisInstance.new(url: server, timeout: redis_timeout) else RedisInstance.new(server) end end @quorum = servers.length / 2 + 1 @retry_count = [:retry_count] || DEFAULT_RETRY_COUNT @retry_delay = [:retry_delay] || DEFAULT_RETRY_DELAY end |
Instance Attribute Details
#testing_mode=(value) ⇒ Object (writeonly)
Sets the attribute testing_mode
3 4 5 |
# File 'lib/redlock/testing.rb', line 3 def testing_mode=(value) @testing_mode = value end |
Instance Method Details
#lock(resource, ttl, options = {}, &block) ⇒ Object
Locks a resource for a given time. Params:
resource
-
the resource (or key) string to be locked.
ttl
-
The time-to-live in ms for the lock.
extend
: A lock (“lock_info”) to extend.
block
-
an optional block to be executed; after its execution, the lock (if successfully
acquired) is automatically unlocked.
40 41 42 43 44 45 46 47 48 49 50 51 52 53 |
# File 'lib/redlock/client.rb', line 40 def lock(resource, ttl, = {}, &block) lock_info = try_lock_instances(resource, ttl, ) if block_given? begin yield lock_info !!lock_info ensure unlock(lock_info) if lock_info end else lock_info end end |
#lock!(*args) ⇒ Object
Locks a resource, executing the received block only after successfully acquiring the lock, and returning its return value as a result. See Redlock::Client#lock for parameters.
65 66 67 68 69 70 71 72 |
# File 'lib/redlock/client.rb', line 65 def lock!(*args) fail 'No block passed' unless block_given? lock(*args) do |lock_info| raise LockError, 'failed to acquire lock' unless lock_info return yield end end |
#try_lock_instances(resource, ttl, options) ⇒ Object
161 162 163 164 165 166 167 168 169 170 171 172 173 |
# File 'lib/redlock/client.rb', line 161 def try_lock_instances(resource, ttl, ) tries = [:extend] ? 1 : @retry_count tries.times do lock_info = lock_instances(resource, ttl, ) return lock_info if lock_info # Wait a random delay before retrying sleep(rand(@retry_delay).to_f / 1000) end false end |
#try_lock_instances_without_testing ⇒ Object
5 6 7 8 9 10 11 12 13 14 15 16 17 |
# File 'lib/redlock/testing.rb', line 5 def try_lock_instances(resource, ttl, ) tries = [:extend] ? 1 : @retry_count tries.times do lock_info = lock_instances(resource, ttl, ) return lock_info if lock_info # Wait a random delay before retrying sleep(rand(@retry_delay).to_f / 1000) end false end |
#unlock(lock_info) ⇒ Object
Unlocks a resource. Params:
lock_info
-
the lock that has been acquired when you locked the resource.
58 59 60 |
# File 'lib/redlock/client.rb', line 58 def unlock(lock_info) @servers.each { |s| s.unlock(lock_info[:resource], lock_info[:value]) } end |
#unlock_without_testing ⇒ Object
Unlocks a resource. Params:
lock_info
-
the lock that has been acquired when you locked the resource.
21 22 23 |
# File 'lib/redlock/testing.rb', line 21 def unlock(lock_info) @servers.each { |s| s.unlock(lock_info[:resource], lock_info[:value]) } end |