class SidekiqUniqueJobs::Lock::BaseLock

@author Mikael Henriksson <mikael@mhenrixon.com>
@abstract
Abstract base class for locks

def self.validate_options(options = {})

Returns:
  • (void) -

Parameters:
  • options (Hash) -- the sidekiq_options given to the worker
def self.validate_options(options = {})
  Validator.validate(options)
end

def call_strategy(origin:)

Other tags:
    Yieldreturn: - the yield is irrelevant, it only provides a mechanism in

Other tags:
    Yieldparam: if - a new job id was set and a block is given

Returns:
  • (void) - the return value is irrelevant

Parameters:
  • origin (Symbol) -- the origin `:client` or `:server`
def call_strategy(origin:)
  new_job_id = nil
  strategy   = strategy_for(origin)
  @attempt  += 1
  strategy.call { new_job_id = lock if strategy.replace? && @attempt < 2 }
  yield if new_job_id && block_given?
end

def callback_safely

def callback_safely
  callback&.call
  item[JID]
rescue StandardError
  reflect(:after_unlock_callback_failed, item)
  raise
end

def client_strategy

def client_strategy
  @client_strategy ||=
    OnConflict.find_strategy(lock_config.on_client_conflict).new(item, redis_pool)
end

def execute

Raises:
  • (NotImplementedError) - needs to be implemented in child class
def execute
  raise NotImplementedError, "##{__method__} needs to be implemented in #{self.class}"
end

def initialize(item, callback, redis_pool = nil)

Parameters:
  • redis_pool (Sidekiq::RedisConnection, ConnectionPool) -- the redis connection
  • callback (Proc) -- the callback to use after unlock
  • item (Hash) -- the Sidekiq job hash
def initialize(item, callback, redis_pool = nil)
  @item       = item
  @callback   = callback
  @redis_pool = redis_pool
  @attempt    = 0
  prepare_item # Used to ease testing
  @lock_config = LockConfig.new(item)
end

def lock

Other tags:
    Yield: - to the caller when given a block

Returns:
  • (String, nil) - the locked jid when properly locked, else nil.

Other tags:
    Note: - Will call a conflict strategy if lock can't be achieved.
def lock
  raise NotImplementedError, "##{__method__} needs to be implemented in #{self.class}"
end

def locksmith

Returns:
  • (SidekiqUniqueJobs::Locksmith) - the locksmith for this sidekiq job

Other tags:
    Api: - private
def locksmith
  @locksmith ||= SidekiqUniqueJobs::Locksmith.new(item, redis_pool)
end

def prepare_item

Returns:
  • (void) - the return value should be irrelevant
def prepare_item
  return if item.key?(LOCK_DIGEST)
  # The below should only be done to ease testing
  # in production this will be done by the middleware
  SidekiqUniqueJobs::Job.prepare(item)
end

def server_strategy

def server_strategy
  @server_strategy ||=
    OnConflict.find_strategy(lock_config.on_server_conflict).new(item, redis_pool)
end

def strategy_for(origin)

def strategy_for(origin)
  case origin
  when :client
    client_strategy
  when :server
    server_strategy
  else
    raise SidekiqUniqueJobs::InvalidArgument,
      "#origin needs to be either `:server` or `:client`"
  end
end

def unlock_and_callback

def unlock_and_callback
  return callback_safely if locksmith.unlock
  reflect(:unlock_failed, item)
end