class SidekiqUniqueJobs::Lock

rubocop:disable Metrics/ClassLength
@author Mikael Henriksson <mikael@zoolutions.se>
Class Lock provides access to information about a lock

def self.create(digest, job_id, lock_info = {})

Returns:
  • (Lock) - a newly lock that has been locked

Parameters:
  • lock_info (Hash) -- information about the lock
  • job_id (String) -- a sidekiq JID
  • digest (String) -- a unique digest
def self.create(digest, job_id, lock_info = {})
  lock = new(digest, time: Timing.now_f)
  lock.lock(job_id, lock_info)
  lock
end

def all_jids

Returns:
  • (Array) - an array with JIDs

Other tags:
    Note: - a JID can be present in 3 different places
def all_jids
  (queued_jids + primed_jids + locked_jids).uniq
end

def changelog

Returns:
  • (Changelog) -

Other tags:
    See: Changelog - for more information
def changelog
  @changelog ||= Changelog.new
end

def changelog_json(job_id, script, message)

Returns:
  • (String) - a JSON string matching the Lua script structure

Parameters:
  • message (String) -- a descriptive message for later review
  • script (String) -- the name of the script generating this entry
  • job_id (String) -- a sidekiq JID
def changelog_json(job_id, script, message)
  dump_json(
    digest: key.digest,
    job_id: job_id,
    script: script,
    message: message,
    time: now_f,
  )
end

def changelogs

Returns:
  • (Array) - an array with changelogs
def changelogs
  changelog.entries(pattern: "*#{key.digest}*")
end

def created_at

Returns:
  • (Float) - a floaty timestamp represantation
def created_at
  @created_at ||= changelogs.first&.[]("time")
end

def del

Returns:
  • (Integer) - the number of keys deleted in redis
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

def digest

Returns:
  • (Redis::String) - a string representation of the key

Other tags:
    Note: - Used for exists checks to avoid enqueuing
def digest
  @digest ||= Redis::String.new(key.digest)
end

def get_key(key)

Returns:
  • (Key) -

Parameters:
  • key (String, Key) --
def get_key(key)
  if key.is_a?(SidekiqUniqueJobs::Key)
    key
  else
    SidekiqUniqueJobs::Key.new(key)
  end
end

def info

Returns:
  • (Redis::Hash) - with lock information
def info
  @info ||= LockInfo.new(key.info)
end

def initialize(key, time: nil)

Parameters:
  • time (Timstamp, Float) -- nil optional timestamp to initiate this lock with
  • key (String, Key) -- either a digest or an instance of a {Key}
def initialize(key, time: nil)
  @key        = get_key(key)
  @created_at = time.is_a?(Float) ? time : time.to_f
end

def inspect

Other tags:
    See: to_s -
def inspect
  to_s
end

def lock(job_id, lock_info = {})

Returns:
  • (void) -

Parameters:
  • lock_info (Hash) -- information about the lock
  • job_id (String) -- a sidekiq JID

Other tags:
    Note: - intended only for testing purposez
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

def locked

Returns:
  • (Redis::Hash) - for locked JIDs
def locked
  @locked ||= Redis::Hash.new(key.locked)
end

def locked_jids(with_values: false)

Returns:
  • (Array) - when given `with_values: false`
  • (Hash) - when given `with_values: true`

Parameters:
  • with_values (true, false) -- false provide the timestamp for the lock
def locked_jids(with_values: false)
  locked.entries(with_values: with_values)
end

def primed

Returns:
  • (Redis::List) - for primed JIDs
def primed
  @primed ||= Redis::List.new(key.primed)
end

def primed_jids

Returns:
  • (Array) - an array with primed job_ids
def primed_jids
  primed.entries
end

def queued

Returns:
  • (Redis::List) - for queued JIDs
def queued
  @queued ||= Redis::List.new(key.queued)
end

def queued_jids

Returns:
  • (Array) - an array with queued job_ids
def queued_jids
  queued.entries
end

def to_s

Returns:
  • (String) -
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

def unlock(job_id)

Returns:
  • (false) - when job_id wasn't locked
  • (true) - when job_id was removed

Parameters:
  • job_id (String) -- a sidekiq JID
def unlock(job_id)
  locked.del(job_id)
end