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
# 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

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



152
153
154
# File 'lib/sidekiq_unique_jobs/lock.rb', line 152

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

#changelogChangelog

A sorted set with changelog entries

Returns:

See Also:



259
260
261
# File 'lib/sidekiq_unique_jobs/lock.rb', line 259

def changelog
  @changelog ||= Changelog.new
end

#changelogsArray<Hash>

Returns all matching changelog entries for this lock

Returns:



194
195
196
# File 'lib/sidekiq_unique_jobs/lock.rb', line 194

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



140
141
142
# File 'lib/sidekiq_unique_jobs/lock.rb', line 140

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



124
125
126
127
128
129
130
131
# File 'lib/sidekiq_unique_jobs/lock.rb', line 124

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:



207
208
209
# File 'lib/sidekiq_unique_jobs/lock.rb', line 207

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

#infoRedis::Hash

Information about the lock

Returns:



247
248
249
# File 'lib/sidekiq_unique_jobs/lock.rb', line 247

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

#inspectObject

See Also:



285
286
287
# File 'lib/sidekiq_unique_jobs/lock.rb', line 285

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



63
64
65
66
67
68
69
70
71
72
73
74
# File 'lib/sidekiq_unique_jobs/lock.rb', line 63

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:



237
238
239
# File 'lib/sidekiq_unique_jobs/lock.rb', line 237

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`



164
165
166
# File 'lib/sidekiq_unique_jobs/lock.rb', line 164

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



100
101
102
103
104
# File 'lib/sidekiq_unique_jobs/lock.rb', line 100

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

#primedRedis::List

The primed list

Returns:



227
228
229
# File 'lib/sidekiq_unique_jobs/lock.rb', line 227

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



184
185
186
# File 'lib/sidekiq_unique_jobs/lock.rb', line 184

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



85
86
87
88
89
# File 'lib/sidekiq_unique_jobs/lock.rb', line 85

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

#queuedRedis::List

The queued list

Returns:



217
218
219
# File 'lib/sidekiq_unique_jobs/lock.rb', line 217

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



174
175
176
# File 'lib/sidekiq_unique_jobs/lock.rb', line 174

def queued_jids
  queued.entries
end

#to_sString

A nicely formatted string with information about this lock

Returns:

  • (String)


269
270
271
272
273
274
275
276
277
278
279
280
# 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(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



114
115
116
# File 'lib/sidekiq_unique_jobs/lock.rb', line 114

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