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: {}, time: Timing.now_f, score: nil) ⇒ 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: {}, time: Timing.now_f, score: nil)
  lock = new(digest, time: time)
  lock.lock(job_id, lock_info, score)
  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



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

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

#changelogChangelog

A sorted set with changelog entries

Returns:

See Also:



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

def changelog
  @changelog ||= Changelog.new
end

#changelogsArray<Hash>

Returns all matching changelog entries for this lock

Returns:



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

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



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

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



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

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:



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

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

#infoRedis::Hash

Information about the lock

Returns:



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

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

#inspectObject

See Also:



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

def inspect
  to_s
end

#lock(job_id, lock_info = {}, score = nil) ⇒ 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
78
# File 'lib/sidekiq_unique_jobs/lock.rb', line 66

def lock(job_id, lock_info = {}, score = nil)
  score ||= now_f
  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, score)
      pipeline.zadd(key.changelog, score, changelog_json(job_id, "queue.lua", "Queued"))
      pipeline.zadd(key.changelog, score, changelog_json(job_id, "lock.lua", "Locked"))
    end
  end
end

#lockedRedis::Hash

The locked hash

Returns:



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

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`



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

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



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

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

#primedRedis::List

The primed list

Returns:



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

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



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

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



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

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

#queuedRedis::List

The queued list

Returns:



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

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



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

def queued_jids
  queued.entries
end

#to_sString

A nicely formatted string with information about this lock

Returns:

  • (String)


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

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



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

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