class RedisLocker::Locker

Constants

NULL_SET_VALUE

Public Class Methods

new(*_args) click to toggle source
# File lib/redis_locker/locker.rb, line 4
def initialize(*_args)
  raise Errors::KeyStringNotSet unless @key_string.is_a?(String)

  setup_redis_set
  loop do
    @instance_hash = rand(36**8).to_s(36)
    break unless redis.sismember(@key_string, @instance_hash)
  end
end

Public Instance Methods

lock() click to toggle source
# File lib/redis_locker/locker.rb, line 14
def lock
  raise NotImplementedError, '#lock has to be implemented'
end
lock!() click to toggle source
# File lib/redis_locker/locker.rb, line 18
def lock!
  raise NotImplementedError, '#lock! has to be implemented'
end
locked?() click to toggle source
# File lib/redis_locker/locker.rb, line 22
def locked?
  raise NotImplementedError, '#locked? has to be implemented'
end
unlock() click to toggle source
# File lib/redis_locker/locker.rb, line 26
def unlock
  raise NotImplementedError, '#unlock has to be implemented'
end
with_redis_lock(strategy: RedisLocker::DEFAULT_STRATEGY, retry_count: RedisLocker::DEFAULT_RETRY_COUNT, retry_interval: RedisLocker::DEFAULT_RETRY_INTERVAL) { || ... } click to toggle source
# File lib/redis_locker/locker.rb, line 30
def with_redis_lock(strategy: RedisLocker::DEFAULT_STRATEGY, retry_count: RedisLocker::DEFAULT_RETRY_COUNT,
                    retry_interval: RedisLocker::DEFAULT_RETRY_INTERVAL, &block)
  raise Errors::UnknownStrategy unless RedisLocker::STRATEGIES.include? strategy

  return respond_to_lock(strategy: strategy, retry_count: retry_count, retry_interval: retry_interval, &block) if locked?

  lock_result = strategy == :exception ? lock! : lock # delegates throwing exception to lock!
  return unless lock_result

  begin
    yield if block
  rescue Exception => e
    unlock
    raise e
  end
  unlock # unlock returns true if everything is ok
end

Private Instance Methods

respond_to_lock(**args, &block) click to toggle source
# File lib/redis_locker/locker.rb, line 50
def respond_to_lock(**args, &block)
  raise Errors::Locked if args[:strategy] == :exception
  return false if args[:strategy] == :silently_die

  # otherwise strategy is retry
  args[:retry_count] -= 1
  raise Errors::MaxRetryCountAchieved if args[:retry_count].negative?

  sleep(args[:retry_interval])
  with_redis_lock(**args, &block)
end
setup_redis_set() click to toggle source
# File lib/redis_locker/locker.rb, line 62
def setup_redis_set
  return if redis.exists?(@key_string)

  redis.sadd(@key_string, NULL_SET_VALUE)
end