class SidekiqUniqueJobs::Lock
Class Lock
provides access to information about a lock
@author Mikael Henriksson <mikael@mhenrixon.com>
Attributes
@!attribute [r] key
@return [String] the entity redis key
Public Class Methods
Initialize a locked lock
@param [String] digest a unique digest @param [String] job_id a sidekiq JID @param [Hash] lock_info information about the lock
@return [Lock] a newly lock that has been locked
# File lib/sidekiq_unique_jobs/lock.rb, line 36 def self.create(digest, job_id, lock_info = {}) lock = new(digest, time: Timing.now_f) lock.lock(job_id, lock_info) lock end
Initialize a new lock
@param [String, Key] key either a digest or an instance of a {Key} @param [Timstamp, Float] time nil optional timestamp to initiate this lock with
# File lib/sidekiq_unique_jobs/lock.rb, line 48 def initialize(key, time: nil) @key = get_key(key) @created_at = time.is_a?(Float) ? time : time.to_f end
Public Instance Methods
Returns all job_id's for this lock
@note a JID can be present in 3 different places
@return [Array<String>] an array with JIDs
# File lib/sidekiq_unique_jobs/lock.rb, line 152 def all_jids (queued_jids + primed_jids + locked_jids).uniq end
A sorted set with changelog entries
@see Changelog
for more information
@return [Changelog]
# File lib/sidekiq_unique_jobs/lock.rb, line 259 def changelog @changelog ||= Changelog.new end
Returns all matching changelog entries for this lock
@return [Array<Hash>] an array with changelogs
# File lib/sidekiq_unique_jobs/lock.rb, line 194 def changelogs changelog.entries(pattern: "*#{key.digest}*") end
Returns either the time the lock was initialized with or
the first changelog entry's timestamp
@return [Float] a floaty timestamp represantation
# File lib/sidekiq_unique_jobs/lock.rb, line 140 def created_at @created_at ||= changelogs.first&.[]("time") end
Deletes all the redis keys for this lock
@return [Integer] the number of keys deleted in redis
# File lib/sidekiq_unique_jobs/lock.rb, line 124 def del redis do |conn| conn.multi do conn.zrem(DIGESTS, key.digest) conn.del(key.digest, key.queued, key.primed, key.locked, key.info) end end end
The digest key
@note Used for exists checks to avoid enqueuing
the same lock twice
@return [Redis::String] a string representation of the key
# File lib/sidekiq_unique_jobs/lock.rb, line 207 def digest @digest ||= Redis::String.new(key.digest) end
Information about the lock
@return [Redis::Hash] with lock information
# File lib/sidekiq_unique_jobs/lock.rb, line 247 def info @info ||= LockInfo.new(key.info) end
@see to_s
# File lib/sidekiq_unique_jobs/lock.rb, line 285 def inspect to_s end
Locks a job_id
@note intended only for testing purposes
@param [String] job_id a sidekiq JID @param [Hash] lock_info information about the lock
@return [void]
# File lib/sidekiq_unique_jobs/lock.rb, line 63 def lock(job_id, lock_info = {}) redis do |conn| conn.multi do conn.set(key.digest, job_id) conn.hset(key.locked, job_id, now_f) info.set(lock_info) conn.zadd(key.digests, now_f, key.digest) conn.zadd(key.changelog, now_f, changelog_json(job_id, "queue.lua", "Queued")) conn.zadd(key.changelog, now_f, changelog_json(job_id, "lock.lua", "Locked")) end end end
The locked hash
@return [Redis::Hash] for locked JIDs
# File lib/sidekiq_unique_jobs/lock.rb, line 237 def locked @locked ||= Redis::Hash.new(key.locked) end
Returns a collection of locked job_id's
@param [true, false] with_values false provide the timestamp for the lock
@return [Hash<String, Float>] when given `with_values: true` @return [Array<String>] when given `with_values: false`
# File lib/sidekiq_unique_jobs/lock.rb, line 164 def locked_jids(with_values: false) locked.entries(with_values: with_values) end
Create the :PRIMED key
@note intended only for testing purposes
@param [String] job_id a sidekiq JID
@return [void]
# File lib/sidekiq_unique_jobs/lock.rb, line 100 def prime(job_id) redis do |conn| conn.lpush(key.primed, job_id) end end
The primed list
@return [Redis::List] for primed JIDs
# File lib/sidekiq_unique_jobs/lock.rb, line 227 def primed @primed ||= Redis::List.new(key.primed) end
Returns the primed JIDs
@return [Array<String>] an array with primed job_ids
# File lib/sidekiq_unique_jobs/lock.rb, line 184 def primed_jids primed.entries end
Create the :QUEUED key
@note intended only for testing purposes
@param [String] job_id a sidekiq JID
@return [void]
# File lib/sidekiq_unique_jobs/lock.rb, line 85 def queue(job_id) redis do |conn| conn.lpush(key.queued, job_id) end end
The queued list
@return [Redis::List] for queued JIDs
# File lib/sidekiq_unique_jobs/lock.rb, line 217 def queued @queued ||= Redis::List.new(key.queued) end
Returns the queued JIDs
@return [Array<String>] an array with queued job_ids
# File lib/sidekiq_unique_jobs/lock.rb, line 174 def queued_jids queued.entries end
A nicely formatted string with information about this lock
@return [String]
# File lib/sidekiq_unique_jobs/lock.rb, line 269 def to_s <<~MESSAGE Lock status for #{key} value: #{digest.value} info: #{info.value} queued_jids: #{queued_jids} primed_jids: #{primed_jids} locked_jids: #{locked_jids} changelogs: #{changelogs} MESSAGE end
Unlock a specific job_id
@param [String] job_id a sidekiq JID
@return [true] when job_id was removed @return [false] when job_id wasn't locked
# File lib/sidekiq_unique_jobs/lock.rb, line 114 def unlock(job_id) locked.del(job_id) end
Private Instance Methods
Generate a changelog entry for the given arguments
@param [String] job_id a sidekiq JID @param [String] script the name of the script generating this entry @param [String] message a descriptive message for later review
@return [String] a JSON
string matching the Lua script structure
# File lib/sidekiq_unique_jobs/lock.rb, line 315 def changelog_json(job_id, script, message) dump_json( digest: key.digest, job_id: job_id, script: script, message: message, time: now_f, ) end
Ensure the key is a {Key}
@param [String, Key] key
@return [Key]
# File lib/sidekiq_unique_jobs/lock.rb, line 298 def get_key(key) if key.is_a?(SidekiqUniqueJobs::Key) key else SidekiqUniqueJobs::Key.new(key) end end