Class: Sidecloq::Locker
- Inherits:
-
Object
- Object
- Sidecloq::Locker
- Includes:
- Utils
- Defined in:
- lib/sidecloq/locker.rb
Overview
Locker obtains or waits for an exclusive lock on a key in redis
Constant Summary collapse
- DEFAULT_LOCK_KEY =
'sidecloq_leader_lock'
Instance Method Summary collapse
-
#initialize(options = {}) ⇒ Locker
constructor
A new instance of Locker.
- #locked? ⇒ Boolean
- #start ⇒ Object
- #stop(timeout = nil) ⇒ Object
- #try_to_get_or_refresh_lock ⇒ Object
-
#with_lock ⇒ Object
blocks until lock is obtained, then yields.
Methods included from Utils
included, #logger, #redis, #will_never_run
Constructor Details
#initialize(options = {}) ⇒ Locker
Returns a new instance of Locker.
8 9 10 11 12 13 14 15 16 17 |
# File 'lib/sidecloq/locker.rb', line 8 def initialize( = {}) # we keep a connection from the pool by default @redis = [:redis] || Sidekiq.redis_pool.checkout @key = [:lock_key] || DEFAULT_LOCK_KEY @ttl = [:ttl] || 60 @check_interval = [:check_interval] || 15 @lock_manager = Redlock::Client.new([@redis]) @obtained_lock = Concurrent::Event.new @lock = nil end |
Instance Method Details
#locked? ⇒ Boolean
36 37 38 |
# File 'lib/sidecloq/locker.rb', line 36 def locked? @obtained_lock.set? end |
#start ⇒ Object
42 43 44 45 46 47 48 49 50 51 |
# File 'lib/sidecloq/locker.rb', line 42 def start logger.debug('Starting locker check task') @check_task = Concurrent::TimerTask.new( execution_interval: @check_interval, run_now: true ) do try_to_get_or_refresh_lock end @check_task.execute end |
#stop(timeout = nil) ⇒ Object
27 28 29 30 31 32 33 34 |
# File 'lib/sidecloq/locker.rb', line 27 def stop(timeout = nil) return unless @check_task logger.debug('Stopping locker check task') @check_task.shutdown @check_task.wait_for_termination(timeout) logger.debug('Stopped locker check task') end |
#try_to_get_or_refresh_lock ⇒ Object
53 54 55 56 57 58 59 60 61 62 63 |
# File 'lib/sidecloq/locker.rb', line 53 def try_to_get_or_refresh_lock # redlock is in ms, not seconds if @lock @lock = @lock_manager.lock(@key, @ttl * 1000, extend: @lock) else @lock = @lock_manager.lock(@key, @ttl * 1000) end @obtained_lock.set if @lock logger.debug("Leader lock #{'not ' unless @lock}held") @lock end |
#with_lock ⇒ Object
blocks until lock is obtained, then yields
20 21 22 23 24 25 |
# File 'lib/sidecloq/locker.rb', line 20 def with_lock start @obtained_lock.wait yield stop end |