class RedisExpLock

Constants

LUA
VERSION

Attributes

expiry[R]
lock_key[R]
lock_uuid[R]
redis[R]
retries[R]
retry_interval[R]

Public Class Methods

new(lock_key, opts) click to toggle source
# File lib/redis_exp_lock.rb, line 22
def initialize(lock_key, opts)
  defaults = {
    :expiry => nil, # in seconds
    :retries => 0,
    :retry_interval => 0.01, # in seconds
  }
  opts = {}.merge(defaults).merge(opts)

  @lock_key = lock_key.to_s
  raise ArgumentError.new('Invalid lock key') unless @lock_key.size > 0
  @lock_uuid = nil

  @redis = opts[:redis]
  @shavaluator = Shavaluator.new(:redis => @redis)
  @shavaluator.add(LUA)

  @expiry = opts[:expiry]
  @retries = opts[:retries]
  @retry_interval = opts[:retry_interval]
end

Public Instance Methods

key_locked?() click to toggle source
# File lib/redis_exp_lock.rb, line 47
def key_locked?
  @redis.exists(@lock_key)
end
key_owned?() click to toggle source
# File lib/redis_exp_lock.rb, line 51
def key_owned?
  !@lock_uuid.nil? && @lock_uuid == @redis.get(@lock_key)
end
lock() click to toggle source
# File lib/redis_exp_lock.rb, line 74
def lock
  attempts = 0
  while attempts <= @retries
    attempts += 1
    return attempts if try_lock
    sleep @retry_interval
  end
  raise TooManyLockAttemptsError
end
locked?() click to toggle source
# File lib/redis_exp_lock.rb, line 43
def locked?
  !@lock_uuid.nil?
end
synchronize(&crit_sec) click to toggle source
# File lib/redis_exp_lock.rb, line 91
def synchronize(&crit_sec)
  attempts = lock
  crit_sec.call attempts
  unlock
end
try_lock() click to toggle source

Attempt to acquire the lock, returning true if the lock was succesfully acquired, and false if not.

# File lib/redis_exp_lock.rb, line 57
def try_lock
  raise AlreadyAcquiredLockError if locked?

  uuid = SecureRandom.uuid
  set_opts = {
    :nx => true
  }
  set_opts[:px] = Integer(@expiry * 1000) if @expiry

  if @redis.set(@lock_key, uuid, set_opts)
    @lock_uuid = uuid
    true
  else
    false
  end
end
unlock() click to toggle source
# File lib/redis_exp_lock.rb, line 84
def unlock
  return false unless locked?
  was_locked = @shavaluator.exec(:delequal, :keys => [@lock_key], :argv => [@lock_uuid]) == 1
  @lock_uuid = nil
  was_locked
end