class Findable::Query::Lock

Public Class Methods

new(lock_key, thread_key, options = {}) click to toggle source
# File lib/findable/query/lock.rb, line 8
def initialize(lock_key, thread_key, options = {})
  @lock_key = lock_key
  @thread_key = thread_key
  @options = options.symbolize_keys!
end

Public Instance Methods

lock() { || ... } click to toggle source
# File lib/findable/query/lock.rb, line 14
def lock
  if Thread.current[@thread_key]
    yield
  else
    Thread.current[@thread_key] = true
    try_lock!(Time.current)
    begin
      yield
    ensure
      Thread.current[@thread_key] = nil
      unlock!
    end
  end
end
unlock!() click to toggle source
# File lib/findable/query/lock.rb, line 29
def unlock!
  redis.del(@lock_key)
end

Private Instance Methods

expiration() click to toggle source
# File lib/findable/query/lock.rb, line 49
def expiration
  (Time.current + timeout).to_f
end
timeout() click to toggle source
# File lib/findable/query/lock.rb, line 53
def timeout
  (@options[:timeout] || 5).to_f
end
try_lock!(start) click to toggle source
# File lib/findable/query/lock.rb, line 34
def try_lock!(start)
  loop do
    break if redis.setnx(@lock_key, expiration)

    current = redis.get(@lock_key).to_f
    if current < Time.current.to_f
      old = redis.getset(@lock_key, expiration).to_f
      break if old < Time.current.to_f
    end

    Kernel.sleep(0.1)
    raise Findable::LockTimeout if (Time.current.to_f - start) > timeout
  end
end