class SidekiqUniqueJobs::Lock::BaseLock
Abstract base class for locks
@abstract @author Mikael Henriksson <mikael@mhenrixon.com>
Attributes
@!attribute [r] attempt
@return [Integer] the current locking attempt
@!attribute [r] callback
@return [Proc] the block to call after unlock
@!attribute [r] item
@return [Hash<String, Object>] the Sidekiq job hash
@!attribute [r] lock_config
@return [LockConfig] a lock configuration
@!attribute [r] redis_pool
@return [Sidekiq::RedisConnection, ConnectionPool, NilClass] the redis connection
Public Class Methods
Source
# File lib/sidekiq_unique_jobs/lock/base_lock.rb, line 38 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
@param [Hash] item the Sidekiq
job hash @param [Proc] callback the callback to use after unlock @param [Sidekiq::RedisConnection, ConnectionPool] redis_pool
the redis connection
Source
# File lib/sidekiq_unique_jobs/lock/base_lock.rb, line 27 def self.validate_options(options = {}) Validator.validate(options) end
Validates that the sidekiq_options for the worker is valid
@param [Hash] options the sidekiq_options given to the worker
@return [void]
Public Instance Methods
Source
# File lib/sidekiq_unique_jobs/lock/base_lock.rb, line 62 def execute raise NotImplementedError, "##{__method__} needs to be implemented in #{self.class}" end
Execute the job in the Sidekiq
server processor @raise [NotImplementedError] needs to be implemented in child class
Source
# File lib/sidekiq_unique_jobs/lock/base_lock.rb, line 56 def lock raise NotImplementedError, "##{__method__} needs to be implemented in #{self.class}" end
Locks a sidekiq job
@note Will call a conflict strategy if lock can’t be achieved.
@return [String, nil] the locked jid when properly locked, else nil.
@yield to the caller when given a block
Source
# File lib/sidekiq_unique_jobs/lock/base_lock.rb, line 72 def locksmith @locksmith ||= SidekiqUniqueJobs::Locksmith.new(item, redis_pool) end
The lock manager/client
@api private @return [SidekiqUniqueJobs::Locksmith] the locksmith for this sidekiq job
Private Instance Methods
Source
# File lib/sidekiq_unique_jobs/lock/base_lock.rb, line 119 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
Call whatever strategry that has been configured
@param [Symbol] origin the origin ‘:client` or `:server`
@return [void] the return value is irrelevant
@yieldparam [void] if a new job id was set and a block is given @yieldreturn [void] the yield is irrelevant, it only provides a mechanism in
one specific situation to yield back to the middleware.
Source
# File lib/sidekiq_unique_jobs/lock/base_lock.rb, line 134 def callback_safely callback&.call item[JID] rescue StandardError reflect(:after_unlock_callback_failed, item) raise end
Source
# File lib/sidekiq_unique_jobs/lock/base_lock.rb, line 154 def client_strategy @client_strategy ||= OnConflict.find_strategy(lock_config.on_client_conflict).new(item, redis_pool) end
Source
# File lib/sidekiq_unique_jobs/lock/base_lock.rb, line 101 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
Eases testing by allowing the lock implementation to add the missing keys to the job hash.
@return [void] the return value should be irrelevant
Source
# File lib/sidekiq_unique_jobs/lock/base_lock.rb, line 159 def server_strategy @server_strategy ||= OnConflict.find_strategy(lock_config.on_server_conflict).new(item, redis_pool) end
Source
# File lib/sidekiq_unique_jobs/lock/base_lock.rb, line 142 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
Source
# File lib/sidekiq_unique_jobs/lock/base_lock.rb, line 128 def unlock_and_callback return callback_safely if locksmith.unlock reflect(:unlock_failed, item) end