Class: SidekiqUniqueJobs::Lock

Inherits:
Object
  • Object
show all
Includes:
Connection, JSON, Timing
Defined in:
lib/sidekiq_unique_jobs/lock.rb,
lib/sidekiq_unique_jobs/lock/base_lock.rb,
lib/sidekiq_unique_jobs/lock/validator.rb,
lib/sidekiq_unique_jobs/lock/until_expired.rb,
lib/sidekiq_unique_jobs/lock/until_executed.rb,
lib/sidekiq_unique_jobs/lock/until_executing.rb,
lib/sidekiq_unique_jobs/lock/while_executing.rb,
lib/sidekiq_unique_jobs/lock/client_validator.rb,
lib/sidekiq_unique_jobs/lock/server_validator.rb,
lib/sidekiq_unique_jobs/lock/while_executing_reject.rb,
lib/sidekiq_unique_jobs/lock/until_and_while_executing.rb

Overview

Class Lock provides access to information about a lock

Author:

Defined Under Namespace

Classes: BaseLock, ClientValidator, ServerValidator, UntilAndWhileExecuting, UntilExecuted, UntilExecuting, UntilExpired, Validator, WhileExecuting, WhileExecutingReject

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from JSON

dump_json, load_json, safe_load_json

Methods included from Timing

clock_stamp, now_f, time_source, timed

Methods included from Connection

included, #redis

Constructor Details

#initialize(key, time: nil) ⇒ Lock

Initialize a new lock

Parameters:

  • key (String, Key)

    either a digest or an instance of a Key

  • time (Timstamp, Float) (defaults to: nil)

    nil optional timestamp to initiate this lock with



48
49
50
51
52
53
54
# File 'lib/sidekiq_unique_jobs/lock.rb', line 48

def initialize(key, time: nil)
  @key = get_key(key)
  time = time.to_f unless time.is_a?(Float)
  return unless time.nonzero?

  @created_at = time
end

Instance Attribute Details

#keyObject (readonly)

Returns the value of attribute key.



25
26
27
# File 'lib/sidekiq_unique_jobs/lock.rb', line 25

def key
  @key
end

Class Method Details

.create(digest, job_id, lock_info = {}) ⇒ Lock

Initialize a locked lock

Parameters:

  • digest (String)

    a unique digest

  • job_id (String)

    a sidekiq JID

  • lock_info (Hash) (defaults to: {})

    information about the lock

Returns:

  • (Lock)

    a newly lock that has been locked



36
37
38
39
40
# 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

Instance Method Details

#all_jidsArray<String>

Note:

a JID can be present in 3 different places

Returns all job_id’s for this lock

Returns:

  • (Array<String>)

    an array with JIDs



155
156
157
# File 'lib/sidekiq_unique_jobs/lock.rb', line 155

def all_jids
  (queued_jids + primed_jids + locked_jids).uniq
end

#changelogChangelog

A sorted set with changelog entries

Returns:

See Also:



262
263
264
# File 'lib/sidekiq_unique_jobs/lock.rb', line 262

def changelog
  @changelog ||= Changelog.new
end

#changelogsArray<Hash>

Returns all matching changelog entries for this lock

Returns:



197
198
199
# File 'lib/sidekiq_unique_jobs/lock.rb', line 197

def changelogs
  changelog.entries(pattern: "*#{key.digest}*")
end

#created_atFloat

Returns either the time the lock was initialized with or

the first changelog entry's timestamp

Returns:

  • (Float)

    a floaty timestamp represantation



143
144
145
# File 'lib/sidekiq_unique_jobs/lock.rb', line 143

def created_at
  @created_at ||= changelogs.first&.[]("time")
end

#delInteger

Deletes all the redis keys for this lock

Returns:

  • (Integer)

    the number of keys deleted in redis



127
128
129
130
131
132
133
134
# File 'lib/sidekiq_unique_jobs/lock.rb', line 127

def del
  redis do |conn|
    conn.multi do |pipeline|
      pipeline.zrem(DIGESTS, key.digest)
      pipeline.del(key.digest, key.queued, key.primed, key.locked, key.info)
    end
  end
end

#digestRedis::String

Note:

Used for exists checks to avoid enqueuing the same lock twice

The digest key

Returns:



210
211
212
# File 'lib/sidekiq_unique_jobs/lock.rb', line 210

def digest
  @digest ||= Redis::String.new(key.digest)
end

#infoRedis::Hash

Information about the lock

Returns:



250
251
252
# File 'lib/sidekiq_unique_jobs/lock.rb', line 250

def info
  @info ||= LockInfo.new(key.info)
end

#inspectObject

See Also:



288
289
290
# File 'lib/sidekiq_unique_jobs/lock.rb', line 288

def inspect
  to_s
end

#lock(job_id, lock_info = {}) ⇒ void

Note:

intended only for testing purposes

This method returns an undefined value.

Locks a job_id

Parameters:

  • job_id (String)

    a sidekiq JID

  • lock_info (Hash) (defaults to: {})

    information about the lock



66
67
68
69
70
71
72
73
74
75
76
77
# File 'lib/sidekiq_unique_jobs/lock.rb', line 66

def lock(job_id, lock_info = {})
  redis do |conn|
    conn.multi do |pipeline|
      pipeline.set(key.digest, job_id)
      pipeline.hset(key.locked, job_id, now_f)
      info.set(lock_info, pipeline)
      add_digest_to_set(pipeline, lock_info)
      pipeline.zadd(key.changelog, now_f, changelog_json(job_id, "queue.lua", "Queued"))
      pipeline.zadd(key.changelog, now_f, changelog_json(job_id, "lock.lua", "Locked"))
    end
  end
end

#lockedRedis::Hash

The locked hash

Returns:



240
241
242
# File 'lib/sidekiq_unique_jobs/lock.rb', line 240

def locked
  @locked ||= Redis::Hash.new(key.locked)
end

#locked_jids(with_values: false) ⇒ Hash<String, Float>, Array<String>

Returns a collection of locked job_id’s

Parameters:

  • with_values (true, false) (defaults to: false)

    false provide the timestamp for the lock

Returns:

  • (Hash<String, Float>)

    when given ‘with_values: true`

  • (Array<String>)

    when given ‘with_values: false`



167
168
169
# File 'lib/sidekiq_unique_jobs/lock.rb', line 167

def locked_jids(with_values: false)
  locked.entries(with_values: with_values)
end

#prime(job_id) ⇒ void

Note:

intended only for testing purposes

This method returns an undefined value.

Create the :PRIMED key

Parameters:

  • job_id (String)

    a sidekiq JID



103
104
105
106
107
# File 'lib/sidekiq_unique_jobs/lock.rb', line 103

def prime(job_id)
  redis do |conn|
    conn.lpush(key.primed, job_id)
  end
end

#primedRedis::List

The primed list

Returns:



230
231
232
# File 'lib/sidekiq_unique_jobs/lock.rb', line 230

def primed
  @primed ||= Redis::List.new(key.primed)
end

#primed_jidsArray<String>

Returns the primed JIDs

Returns:

  • (Array<String>)

    an array with primed job_ids



187
188
189
# File 'lib/sidekiq_unique_jobs/lock.rb', line 187

def primed_jids
  primed.entries
end

#queue(job_id) ⇒ void

Note:

intended only for testing purposes

This method returns an undefined value.

Create the :QUEUED key

Parameters:

  • job_id (String)

    a sidekiq JID



88
89
90
91
92
# File 'lib/sidekiq_unique_jobs/lock.rb', line 88

def queue(job_id)
  redis do |conn|
    conn.lpush(key.queued, job_id)
  end
end

#queuedRedis::List

The queued list

Returns:



220
221
222
# File 'lib/sidekiq_unique_jobs/lock.rb', line 220

def queued
  @queued ||= Redis::List.new(key.queued)
end

#queued_jidsArray<String>

Returns the queued JIDs

Returns:

  • (Array<String>)

    an array with queued job_ids



177
178
179
# File 'lib/sidekiq_unique_jobs/lock.rb', line 177

def queued_jids
  queued.entries
end

#to_sString

A nicely formatted string with information about this lock

Returns:

  • (String)


272
273
274
275
276
277
278
279
280
281
282
283
# File 'lib/sidekiq_unique_jobs/lock.rb', line 272

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(job_id) ⇒ true, false

Unlock a specific job_id

Parameters:

  • job_id (String)

    a sidekiq JID

Returns:

  • (true)

    when job_id was removed

  • (false)

    when job_id wasn’t locked



117
118
119
# File 'lib/sidekiq_unique_jobs/lock.rb', line 117

def unlock(job_id)
  locked.del(job_id)
end