Class: EM::Hiredis::PersistentLock
- Inherits:
-
Object
- Object
- EM::Hiredis::PersistentLock
- Defined in:
- lib/em-hiredis/persistent_lock.rb
Overview
A lock that automatically re-acquires a lock before it loses it
The lock is configured with the following two parameters
:lock_timeout - Specifies how long each lock is acquired for. Setting
this low means that locks need to be re-acquired very often, but a long
timout means that a process that fails without cleaning up after itself
(i.e. without releasing it's underlying lock) will block the anther
process from picking up this lock
replaced for a long while
:retry_interval - Specifies how frequently to retry acquiring the lock in
the case that the lock is held by another process, or there's an error
communicating with redis
Instance Method Summary collapse
-
#acquire ⇒ Object
Acquire the lock (called automatically by initialize).
-
#initialize(redis, key, options = {}) ⇒ PersistentLock
constructor
A new instance of PersistentLock.
- #locked? ⇒ Boolean
- #onlocked(&blk) ⇒ Object
- #onunlocked(&blk) ⇒ Object
- #stop ⇒ Object
Constructor Details
#initialize(redis, key, options = {}) ⇒ PersistentLock
Returns a new instance of PersistentLock.
20 21 22 23 24 25 26 27 28 29 30 31 |
# File 'lib/em-hiredis/persistent_lock.rb', line 20 def initialize(redis, key, = {}) @redis, @key = redis, key @timeout = [:lock_timeout] || 100 @retry_timeout = [:retry_interval] || 60 @lock = EM::Hiredis::Lock.new(redis, key, @timeout) @locked = false EM.next_tick { @running = true acquire } end |
Instance Method Details
#acquire ⇒ Object
Acquire the lock (called automatically by initialize)
34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
# File 'lib/em-hiredis/persistent_lock.rb', line 34 def acquire return unless @running @lock.acquire.callback { if !@locked @onlocked.call if @onlocked @locked = true end # Re-acquire lock near the end of the period @extend_timer = EM.add_timer(@timeout.to_f * 2 / 3) { acquire() } }.errback { |e| if @locked # We were previously locked @onunlocked.call if @onunlocked @locked = false end if e.kind_of?(EM::Hiredis::RedisError) err = e.redis_error EM::Hiredis.logger.warn "Unexpected error acquiring #{@lock} #{err}" end @retry_timer = EM.add_timer(@retry_timeout) { acquire() unless @locked } } end |
#locked? ⇒ Boolean
77 78 79 |
# File 'lib/em-hiredis/persistent_lock.rb', line 77 def locked? @locked end |
#onlocked(&blk) ⇒ Object
17 |
# File 'lib/em-hiredis/persistent_lock.rb', line 17 def onlocked(&blk); @onlocked = blk; self; end |
#onunlocked(&blk) ⇒ Object
18 |
# File 'lib/em-hiredis/persistent_lock.rb', line 18 def onunlocked(&blk); @onunlocked = blk; self; end |
#stop ⇒ Object
65 66 67 68 69 70 71 72 73 74 75 |
# File 'lib/em-hiredis/persistent_lock.rb', line 65 def stop @running = false EM.cancel_timer(@extend_timer) if @extend_timer EM.cancel_timer(@retry_timer) if @retry_timer if @locked # We were previously locked @onunlocked.call if @onunlocked @locked = false end @lock.unlock end |