sidekiq-unique-jobs 7.1.5 → 7.1.25

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of sidekiq-unique-jobs might be problematic. Click here for more details.

Files changed (51) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +244 -4
  3. data/README.md +16 -14
  4. data/lib/sidekiq_unique_jobs/batch_delete.rb +6 -6
  5. data/lib/sidekiq_unique_jobs/changelog.rb +3 -3
  6. data/lib/sidekiq_unique_jobs/config.rb +43 -4
  7. data/lib/sidekiq_unique_jobs/constants.rb +44 -44
  8. data/lib/sidekiq_unique_jobs/deprecation.rb +30 -0
  9. data/lib/sidekiq_unique_jobs/digests.rb +6 -9
  10. data/lib/sidekiq_unique_jobs/exceptions.rb +4 -3
  11. data/lib/sidekiq_unique_jobs/json.rb +7 -0
  12. data/lib/sidekiq_unique_jobs/lock/base_lock.rb +30 -22
  13. data/lib/sidekiq_unique_jobs/lock/until_and_while_executing.rb +9 -3
  14. data/lib/sidekiq_unique_jobs/lock/until_executed.rb +14 -4
  15. data/lib/sidekiq_unique_jobs/lock/until_executing.rb +14 -4
  16. data/lib/sidekiq_unique_jobs/lock/until_expired.rb +13 -5
  17. data/lib/sidekiq_unique_jobs/lock/while_executing.rb +9 -4
  18. data/lib/sidekiq_unique_jobs/lock.rb +10 -10
  19. data/lib/sidekiq_unique_jobs/lock_args.rb +19 -15
  20. data/lib/sidekiq_unique_jobs/lock_config.rb +6 -6
  21. data/lib/sidekiq_unique_jobs/lock_digest.rb +6 -6
  22. data/lib/sidekiq_unique_jobs/lock_info.rb +2 -2
  23. data/lib/sidekiq_unique_jobs/lock_timeout.rb +4 -4
  24. data/lib/sidekiq_unique_jobs/lock_ttl.rb +5 -5
  25. data/lib/sidekiq_unique_jobs/locksmith.rb +5 -4
  26. data/lib/sidekiq_unique_jobs/logging.rb +9 -0
  27. data/lib/sidekiq_unique_jobs/lua/lock.lua +3 -3
  28. data/lib/sidekiq_unique_jobs/lua/shared/_common.lua +1 -1
  29. data/lib/sidekiq_unique_jobs/lua/unlock.lua +12 -5
  30. data/lib/sidekiq_unique_jobs/middleware/client.rb +3 -1
  31. data/lib/sidekiq_unique_jobs/middleware/server.rb +2 -0
  32. data/lib/sidekiq_unique_jobs/middleware.rb +4 -4
  33. data/lib/sidekiq_unique_jobs/on_conflict/reject.rb +4 -4
  34. data/lib/sidekiq_unique_jobs/on_conflict/reschedule.rb +3 -3
  35. data/lib/sidekiq_unique_jobs/options_with_fallback.rb +5 -7
  36. data/lib/sidekiq_unique_jobs/orphans/manager.rb +38 -10
  37. data/lib/sidekiq_unique_jobs/orphans/ruby_reaper.rb +77 -14
  38. data/lib/sidekiq_unique_jobs/redis/string.rb +3 -1
  39. data/lib/sidekiq_unique_jobs/reflectable.rb +11 -2
  40. data/lib/sidekiq_unique_jobs/reflections.rb +12 -1
  41. data/lib/sidekiq_unique_jobs/server.rb +13 -1
  42. data/lib/sidekiq_unique_jobs/sidekiq_unique_ext.rb +35 -13
  43. data/lib/sidekiq_unique_jobs/sidekiq_worker_methods.rb +40 -21
  44. data/lib/sidekiq_unique_jobs/testing.rb +45 -20
  45. data/lib/sidekiq_unique_jobs/timer_task.rb +266 -45
  46. data/lib/sidekiq_unique_jobs/timing.rb +1 -1
  47. data/lib/sidekiq_unique_jobs/upgrade_locks.rb +6 -6
  48. data/lib/sidekiq_unique_jobs/version.rb +1 -1
  49. data/lib/sidekiq_unique_jobs/web/helpers.rb +1 -1
  50. data/lib/tasks/changelog.rake +16 -16
  51. metadata +11 -15
@@ -7,6 +7,13 @@ module SidekiqUniqueJobs
7
7
  # @author Mikael Henriksson <mikael@mhenrixon.com>
8
8
  #
9
9
  class Deprecation
10
+ #
11
+ # Mute warnings from this gem in a threaded context
12
+ #
13
+ #
14
+ # @return [void] <description>
15
+ #
16
+ # @yieldreturn [void]
10
17
  def self.muted
11
18
  orig_val = Thread.current[:uniquejobs_mute_deprecations]
12
19
  Thread.current[:uniquejobs_mute_deprecations] = true
@@ -15,21 +22,44 @@ module SidekiqUniqueJobs
15
22
  Thread.current[:uniquejobs_mute_deprecations] = orig_val
16
23
  end
17
24
 
25
+ #
26
+ # Check if deprecation warnings have been muted
27
+ #
28
+ #
29
+ # @return [true,false]
30
+ #
18
31
  def self.muted?
19
32
  Thread.current[:uniquejobs_mute_deprecations] == true
20
33
  end
21
34
 
35
+ #
36
+ # Warn about deprecation
37
+ #
38
+ # @param [String] msg a descriptive reason for why the deprecation
39
+ #
40
+ # @return [void]
41
+ #
22
42
  def self.warn(msg)
23
43
  return if SidekiqUniqueJobs::Deprecation.muted?
24
44
 
25
45
  warn "DEPRECATION WARNING: #{msg}"
46
+ nil
26
47
  end
27
48
 
49
+ #
50
+ # Warn about deprecation and provide a context
51
+ #
52
+ # @param [String] msg a descriptive reason for why the deprecation
53
+ #
54
+ # @return [void]
55
+ #
28
56
  def self.warn_with_backtrace(msg)
29
57
  return if SidekiqUniqueJobs::Deprecation.muted?
30
58
 
31
59
  trace = "\n\nCALLED FROM:\n#{caller.join("\n")}"
32
60
  warn(msg + trace)
61
+
62
+ nil
33
63
  end
34
64
  end
35
65
  end
@@ -31,7 +31,8 @@ module SidekiqUniqueJobs
31
31
  #
32
32
  # @param [String] pattern a key pattern to match with
33
33
  # @param [Integer] count the maximum number
34
- # @return [Array<String>] with unique digests
34
+ # @return [Hash<String,Float>] Hash mapping of digest matching the given pattern and score
35
+
35
36
  def delete_by_pattern(pattern, count: DEFAULT_COUNT)
36
37
  result, elapsed = timed do
37
38
  digests = entries(pattern: pattern, count: count).keys
@@ -80,11 +81,7 @@ module SidekiqUniqueJobs
80
81
  options[:match] = pattern
81
82
  options[:count] = count
82
83
 
83
- result = redis { |conn| conn.zscan_each(key, **options).to_a }
84
-
85
- result.each_with_object({}) do |entry, hash|
86
- hash[entry[0]] = entry[1]
87
- end
84
+ redis { |conn| conn.zscan_each(key, **options).to_a }.to_h
88
85
  end
89
86
 
90
87
  #
@@ -98,9 +95,9 @@ module SidekiqUniqueJobs
98
95
  #
99
96
  def page(cursor: 0, pattern: SCAN_PATTERN, page_size: 100)
100
97
  redis do |conn|
101
- total_size, digests = conn.multi do
102
- conn.zcard(key)
103
- conn.zscan(key, cursor, match: pattern, count: page_size)
98
+ total_size, digests = conn.multi do |pipeline|
99
+ pipeline.zcard(key)
100
+ pipeline.zscan(key, cursor, match: pattern, count: page_size)
104
101
  end
105
102
 
106
103
  [
@@ -22,6 +22,7 @@ module SidekiqUniqueJobs
22
22
  # Raised when no block was given
23
23
  #
24
24
  class NoBlockGiven < SidekiqUniqueJobs::UniqueJobsError; end
25
+
25
26
  #
26
27
  # Raised when a notification has been mistyped
27
28
  #
@@ -71,14 +72,14 @@ module SidekiqUniqueJobs
71
72
  class InvalidUniqueArguments < UniqueJobsError
72
73
  def initialize(options)
73
74
  given = options[:given]
74
- worker_class = options[:worker_class]
75
+ job_class = options[:job_class]
75
76
  lock_args_method = options[:lock_args_method]
76
- lock_args_meth = worker_class.method(lock_args_method)
77
+ lock_args_meth = job_class.method(lock_args_method)
77
78
  num_args = lock_args_meth.arity
78
79
  source_location = lock_args_meth.source_location
79
80
 
80
81
  super(
81
- "#{worker_class}##{lock_args_method} takes #{num_args} arguments, received #{given.inspect}" \
82
+ "#{job_class}##{lock_args_method} takes #{num_args} arguments, received #{given.inspect}" \
82
83
  "\n\n" \
83
84
  " #{source_location.join(':')}"
84
85
  )
@@ -20,6 +20,13 @@ module SidekiqUniqueJobs
20
20
  ::JSON.parse(string)
21
21
  end
22
22
 
23
+ #
24
+ # Prevents trying JSON.load from raising errors given argument is a hash
25
+ #
26
+ # @param [String, Hash] string the JSON string to parse
27
+ #
28
+ # @return [Hash,Array]
29
+ #
23
30
  def safe_load_json(string)
24
31
  return string if string.is_a?(Hash)
25
32
 
@@ -91,6 +91,13 @@ module SidekiqUniqueJobs
91
91
  # @return [Integer] the current locking attempt
92
92
  attr_reader :attempt
93
93
 
94
+ #
95
+ # Eases testing by allowing the lock implementation to add the missing
96
+ # keys to the job hash.
97
+ #
98
+ #
99
+ # @return [void] the return value should be irrelevant
100
+ #
94
101
  def prepare_item
95
102
  return if item.key?(LOCK_DIGEST)
96
103
 
@@ -100,33 +107,22 @@ module SidekiqUniqueJobs
100
107
  end
101
108
 
102
109
  #
103
- # Handle when lock failed
110
+ # Call whatever strategry that has been configured
104
111
  #
105
- # @param [Symbol] location: :client or :server
112
+ # @param [Symbol] origin: the origin `:client` or `:server`
106
113
  #
107
- # @return [void]
114
+ # @return [void] the return value is irrelevant
108
115
  #
109
- def lock_failed(origin: :client)
110
- reflect(:lock_failed, item)
111
- call_strategy(origin: origin)
112
- end
113
-
116
+ # @yieldparam [void] if a new job id was set and a block is given
117
+ # @yieldreturn [void] the yield is irrelevant, it only provides a mechanism in
118
+ # one specific situation to yield back to the middleware.
114
119
  def call_strategy(origin:)
115
- @attempt += 1
120
+ new_job_id = nil
121
+ strategy = strategy_for(origin)
122
+ @attempt += 1
116
123
 
117
- case origin
118
- when :client
119
- client_strategy.call { lock if replace? }
120
- when :server
121
- server_strategy.call { lock if replace? }
122
- else
123
- raise SidekiqUniqueJobs::InvalidArgument,
124
- "either `for: :server` or `for: :client` needs to be specified"
125
- end
126
- end
127
-
128
- def replace?
129
- client_strategy.replace? && attempt < 2
124
+ strategy.call { new_job_id = lock if strategy.replace? && @attempt < 2 }
125
+ yield if new_job_id && block_given?
130
126
  end
131
127
 
132
128
  def unlock_and_callback
@@ -143,6 +139,18 @@ module SidekiqUniqueJobs
143
139
  raise
144
140
  end
145
141
 
142
+ def strategy_for(origin)
143
+ case origin
144
+ when :client
145
+ client_strategy
146
+ when :server
147
+ server_strategy
148
+ else
149
+ raise SidekiqUniqueJobs::InvalidArgument,
150
+ "#origin needs to be either `:server` or `:client`"
151
+ end
152
+ end
153
+
146
154
  def client_strategy
147
155
  @client_strategy ||=
148
156
  OnConflict.find_strategy(lock_config.on_client_conflict).new(item, redis_pool)
@@ -22,9 +22,15 @@ module SidekiqUniqueJobs
22
22
  #
23
23
  # @yield to the caller when given a block
24
24
  #
25
- def lock(origin: :client)
26
- return lock_failed(origin: origin) unless (token = locksmith.lock)
27
- return yield token if block_given?
25
+ def lock(origin: :client, &block)
26
+ unless (token = locksmith.lock)
27
+ reflect(:lock_failed, item)
28
+ call_strategy(origin: origin, &block)
29
+
30
+ return
31
+ end
32
+
33
+ yield if block
28
34
 
29
35
  token
30
36
  end
@@ -17,9 +17,15 @@ module SidekiqUniqueJobs
17
17
  #
18
18
  # @yield to the caller when given a block
19
19
  #
20
- def lock
21
- return lock_failed(origin: :client) unless (token = locksmith.lock)
22
- return yield token if block_given?
20
+ def lock(&block)
21
+ unless (token = locksmith.lock)
22
+ reflect(:lock_failed, item)
23
+ call_strategy(origin: :client, &block)
24
+
25
+ return
26
+ end
27
+
28
+ yield if block
23
29
 
24
30
  token
25
31
  end
@@ -27,10 +33,14 @@ module SidekiqUniqueJobs
27
33
  # Executes in the Sidekiq server process
28
34
  # @yield to the worker class perform method
29
35
  def execute
30
- locksmith.execute do
36
+ executed = locksmith.execute do
31
37
  yield
32
38
  unlock_and_callback
33
39
  end
40
+
41
+ reflect(:execution_failed, item) unless executed
42
+
43
+ nil
34
44
  end
35
45
  end
36
46
  end
@@ -15,11 +15,17 @@ module SidekiqUniqueJobs
15
15
  #
16
16
  # @return [String, nil] the locked jid when properly locked, else nil.
17
17
  #
18
- def lock
19
- return lock_failed unless (job_id = locksmith.lock)
20
- return yield job_id if block_given?
18
+ def lock(&block)
19
+ unless (token = locksmith.lock)
20
+ reflect(:lock_failed, item)
21
+ call_strategy(origin: :client, &block)
21
22
 
22
- job_id
23
+ return
24
+ end
25
+
26
+ yield if block
27
+
28
+ token
23
29
  end
24
30
 
25
31
  # Executes in the Sidekiq server process
@@ -27,6 +33,10 @@ module SidekiqUniqueJobs
27
33
  def execute
28
34
  callback_safely if locksmith.unlock
29
35
  yield
36
+ rescue StandardError => ex
37
+ reflect(:execution_failed, item, ex)
38
+ locksmith.lock(wait: 1)
39
+ raise
30
40
  end
31
41
  end
32
42
  end
@@ -17,17 +17,25 @@ module SidekiqUniqueJobs
17
17
  #
18
18
  # @yield to the caller when given a block
19
19
  #
20
- def lock
21
- return lock_failed unless (job_id = locksmith.lock)
22
- return yield job_id if block_given?
20
+ def lock(&block)
21
+ unless (token = locksmith.lock)
22
+ reflect(:lock_failed, item)
23
+ call_strategy(origin: :client, &block)
23
24
 
24
- job_id
25
+ return
26
+ end
27
+
28
+ yield if block
29
+
30
+ token
25
31
  end
26
32
 
27
33
  # Executes in the Sidekiq server process
28
34
  # @yield to the worker class perform method
29
35
  def execute(&block)
30
- locksmith.execute(&block)
36
+ executed = locksmith.execute(&block)
37
+
38
+ reflect(:execution_failed, item) unless executed
31
39
  end
32
40
  end
33
41
  end
@@ -11,7 +11,7 @@ module SidekiqUniqueJobs
11
11
  #
12
12
  # @author Mikael Henriksson <mikael@mhenrixon.com>
13
13
  class WhileExecuting < BaseLock
14
- RUN_SUFFIX ||= ":RUN"
14
+ RUN_SUFFIX = ":RUN"
15
15
 
16
16
  include SidekiqUniqueJobs::OptionsWithFallback
17
17
  include SidekiqUniqueJobs::Logging::Middleware
@@ -30,7 +30,7 @@ module SidekiqUniqueJobs
30
30
  # @return [true] always returns true
31
31
  def lock
32
32
  job_id = item[JID]
33
- yield job_id if block_given?
33
+ yield if block_given?
34
34
 
35
35
  job_id
36
36
  end
@@ -38,14 +38,19 @@ module SidekiqUniqueJobs
38
38
  # Executes in the Sidekiq server process.
39
39
  # These jobs are locked in the server process not from the client
40
40
  # @yield to the worker class perform method
41
- def execute
41
+ def execute(&block)
42
42
  with_logging_context do
43
- call_strategy(origin: :server) unless locksmith.execute do
43
+ executed = locksmith.execute do
44
44
  yield
45
45
  callback_safely if locksmith.unlock
46
46
  ensure
47
47
  locksmith.unlock
48
48
  end
49
+
50
+ unless executed
51
+ reflect(:execution_failed, item)
52
+ call_strategy(origin: :server, &block)
53
+ end
49
54
  end
50
55
  end
51
56
 
@@ -62,13 +62,13 @@ module SidekiqUniqueJobs
62
62
  #
63
63
  def lock(job_id, lock_info = {})
64
64
  redis do |conn|
65
- conn.multi do
66
- conn.set(key.digest, job_id)
67
- conn.hset(key.locked, job_id, now_f)
68
- info.set(lock_info)
69
- conn.zadd(key.digests, now_f, key.digest)
70
- conn.zadd(key.changelog, now_f, changelog_json(job_id, "queue.lua", "Queued"))
71
- conn.zadd(key.changelog, now_f, changelog_json(job_id, "lock.lua", "Locked"))
65
+ conn.multi do |pipeline|
66
+ pipeline.set(key.digest, job_id)
67
+ pipeline.hset(key.locked, job_id, now_f)
68
+ info.set(lock_info, pipeline)
69
+ pipeline.zadd(key.digests, now_f, key.digest)
70
+ pipeline.zadd(key.changelog, now_f, changelog_json(job_id, "queue.lua", "Queued"))
71
+ pipeline.zadd(key.changelog, now_f, changelog_json(job_id, "lock.lua", "Locked"))
72
72
  end
73
73
  end
74
74
  end
@@ -123,9 +123,9 @@ module SidekiqUniqueJobs
123
123
  #
124
124
  def del
125
125
  redis do |conn|
126
- conn.multi do
127
- conn.zrem(DIGESTS, key.digest)
128
- conn.del(key.digest, key.queued, key.primed, key.locked, key.info)
126
+ conn.multi do |pipeline|
127
+ pipeline.zrem(DIGESTS, key.digest)
128
+ pipeline.del(key.digest, key.queued, key.primed, key.locked, key.info)
129
129
  end
130
130
  end
131
131
  end
@@ -26,15 +26,15 @@ module SidekiqUniqueJobs
26
26
 
27
27
  # @param [Hash] item a Sidekiq job hash
28
28
  def initialize(item)
29
- @item = item
30
- @worker_class = item[CLASS]
31
- @args = item[ARGS]
29
+ @item = item
30
+ @args = item[ARGS]
31
+ self.job_class = item[CLASS]
32
32
  end
33
33
 
34
34
  # The unique arguments to use for creating a lock
35
35
  # @return [Array] the arguments filters by the {#filtered_args} method if {#lock_args_enabled?}
36
36
  def lock_args
37
- @lock_args ||= filtered_args
37
+ @lock_args ||= filtered_args || []
38
38
  end
39
39
 
40
40
  # Checks if the worker class has enabled lock_args
@@ -83,31 +83,31 @@ module SidekiqUniqueJobs
83
83
 
84
84
  # Filters unique arguments by method configured in the sidekiq worker
85
85
  # @param [Array] args the arguments passed to the sidekiq worker
86
- # @return [Array] unfiltered unless {#worker_method_defined?}
86
+ # @return [Array] unfiltered unless {#job_method_defined?}
87
87
  # @return [Array] with the filtered arguments
88
88
  def filter_by_symbol(args)
89
- return args unless worker_method_defined?(lock_args_method)
89
+ return args unless job_method_defined?(lock_args_method)
90
90
 
91
- worker_class.send(lock_args_method, args)
91
+ job_class.send(lock_args_method, args)
92
92
  rescue ArgumentError
93
93
  raise SidekiqUniqueJobs::InvalidUniqueArguments,
94
94
  given: args,
95
- worker_class: worker_class,
95
+ job_class: job_class,
96
96
  lock_args_method: lock_args_method
97
97
  end
98
98
 
99
99
  # The method to use for filtering unique arguments
100
100
  def lock_args_method
101
- @lock_args_method ||= worker_options.slice(LOCK_ARGS_METHOD, UNIQUE_ARGS_METHOD).values.first
102
- @lock_args_method ||= :lock_args if worker_method_defined?(:lock_args)
103
- @lock_args_method ||= :unique_args if worker_method_defined?(:unique_args)
101
+ @lock_args_method ||= job_options.slice(LOCK_ARGS_METHOD, UNIQUE_ARGS_METHOD).values.first
102
+ @lock_args_method ||= :lock_args if job_method_defined?(:lock_args)
103
+ @lock_args_method ||= :unique_args if job_method_defined?(:unique_args)
104
104
  @lock_args_method ||= default_lock_args_method
105
105
  end
106
106
 
107
107
  # The global worker options defined in Sidekiq directly
108
108
  def default_lock_args_method
109
- default_worker_options[LOCK_ARGS_METHOD] ||
110
- default_worker_options[UNIQUE_ARGS_METHOD]
109
+ default_job_options[LOCK_ARGS_METHOD] ||
110
+ default_job_options[UNIQUE_ARGS_METHOD]
111
111
  end
112
112
 
113
113
  #
@@ -116,8 +116,12 @@ module SidekiqUniqueJobs
116
116
  #
117
117
  # @return [Hash<String, Object>]
118
118
  #
119
- def default_worker_options
120
- @default_worker_options ||= Sidekiq.default_worker_options.stringify_keys
119
+ def default_job_options
120
+ @default_job_options ||= if Sidekiq.respond_to?(:default_job_options)
121
+ Sidekiq.default_job_options.stringify_keys
122
+ else
123
+ Sidekiq.default_worker_options.stringify_keys
124
+ end
121
125
  end
122
126
  end
123
127
  end
@@ -13,9 +13,9 @@ module SidekiqUniqueJobs
13
13
  # @return [Symbol] the type of lock
14
14
  attr_reader :type
15
15
  #
16
- # @!attribute [r] worker
17
- # @return [Symbol] the worker class
18
- attr_reader :worker
16
+ # @!attribute [r] job
17
+ # @return [Symbol] the job class
18
+ attr_reader :job
19
19
  #
20
20
  # @!attribute [r] limit
21
21
  # @return [Integer] the number of simultaneous locks
@@ -58,7 +58,7 @@ module SidekiqUniqueJobs
58
58
 
59
59
  def initialize(job_hash = {})
60
60
  @type = job_hash[LOCK]&.to_sym
61
- @worker = SidekiqUniqueJobs.safe_constantize(job_hash[CLASS])
61
+ @job = SidekiqUniqueJobs.safe_constantize(job_hash[CLASS])
62
62
  @limit = job_hash.fetch(LOCK_LIMIT, 1)&.to_i
63
63
  @timeout = job_hash.fetch(LOCK_TIMEOUT, 0)&.to_i
64
64
  @ttl = job_hash.fetch(LOCK_TTL) { job_hash.fetch(LOCK_EXPIRATION, nil) }.to_i
@@ -113,13 +113,13 @@ module SidekiqUniqueJobs
113
113
 
114
114
  # the strategy to use as conflict resolution from sidekiq client
115
115
  def on_client_conflict
116
- @on_client_conflict ||= on_conflict["client"] if on_conflict.is_a?(Hash)
116
+ @on_client_conflict ||= on_conflict["client"] || on_conflict[:client] if on_conflict.is_a?(Hash)
117
117
  @on_client_conflict ||= on_conflict
118
118
  end
119
119
 
120
120
  # the strategy to use as conflict resolution from sidekiq server
121
121
  def on_server_conflict
122
- @on_server_conflict ||= on_conflict["server"] if on_conflict.is_a?(Hash)
122
+ @on_server_conflict ||= on_conflict["server"] || on_conflict[:server] if on_conflict.is_a?(Hash)
123
123
  @on_server_conflict ||= on_conflict
124
124
  end
125
125
  end
@@ -36,10 +36,10 @@ module SidekiqUniqueJobs
36
36
 
37
37
  # @param [Hash] item a Sidekiq job hash
38
38
  def initialize(item)
39
- @item = item
40
- @worker_class = item[CLASS]
41
- @lock_args = item.slice(LOCK_ARGS, UNIQUE_ARGS).values.first # TODO: Deprecate UNIQUE_ARGS
42
- @lock_prefix = item.slice(LOCK_PREFIX, UNIQUE_PREFIX).values.first # TODO: Deprecate UNIQUE_PREFIX
39
+ @item = item
40
+ @lock_args = item[LOCK_ARGS] || item[UNIQUE_ARGS] # TODO: Deprecate UNIQUE_ARGS
41
+ @lock_prefix = item[LOCK_PREFIX] || item[UNIQUE_PREFIX] # TODO: Deprecate UNIQUE_PREFIX
42
+ self.job_class = item[CLASS]
43
43
  end
44
44
 
45
45
  # Memoized lock_digest
@@ -67,13 +67,13 @@ module SidekiqUniqueJobs
67
67
  # Checks if we should disregard the queue when creating the unique digest
68
68
  # @return [true, false]
69
69
  def unique_across_queues?
70
- item[UNIQUE_ACROSS_QUEUES] || worker_options[UNIQUE_ACROSS_QUEUES]
70
+ item[UNIQUE_ACROSS_QUEUES] || job_options[UNIQUE_ACROSS_QUEUES]
71
71
  end
72
72
 
73
73
  # Checks if we should disregard the worker when creating the unique digest
74
74
  # @return [true, false]
75
75
  def unique_across_workers?
76
- item[UNIQUE_ACROSS_WORKERS] || worker_options[UNIQUE_ACROSS_WORKERS]
76
+ item[UNIQUE_ACROSS_WORKERS] || job_options[UNIQUE_ACROSS_WORKERS]
77
77
  end
78
78
  end
79
79
  end
@@ -55,13 +55,13 @@ module SidekiqUniqueJobs
55
55
  #
56
56
  # @return [Hash]
57
57
  #
58
- def set(obj)
58
+ def set(obj, pipeline = nil)
59
59
  return unless SidekiqUniqueJobs.config.lock_info
60
60
  raise InvalidArgument, "argument `obj` (#{obj}) needs to be a hash" unless obj.is_a?(Hash)
61
61
 
62
62
  json = dump_json(obj)
63
63
  @value = load_json(json)
64
- super(json)
64
+ super(json, pipeline)
65
65
  value
66
66
  end
67
67
  end
@@ -30,8 +30,8 @@ module SidekiqUniqueJobs
30
30
  # @option item [String] :class the class of the sidekiq worker
31
31
  # @option item [Float] :at the unix time the job is scheduled at
32
32
  def initialize(item)
33
- @item = item
34
- @worker_class = item[CLASS]
33
+ @item = item
34
+ self.job_class = item[CLASS]
35
35
  end
36
36
 
37
37
  #
@@ -42,9 +42,9 @@ module SidekiqUniqueJobs
42
42
  # @return [Integer, nil]
43
43
  #
44
44
  def calculate
45
- timeout = default_worker_options[LOCK_TIMEOUT]
45
+ timeout = default_job_options[LOCK_TIMEOUT]
46
46
  timeout = default_lock_timeout if default_lock_timeout
47
- timeout = worker_options[LOCK_TIMEOUT] if worker_options.key?(LOCK_TIMEOUT)
47
+ timeout = job_options[LOCK_TIMEOUT] if job_options.key?(LOCK_TIMEOUT)
48
48
  timeout
49
49
  end
50
50
 
@@ -33,8 +33,8 @@ module SidekiqUniqueJobs
33
33
  # @option item [String] :class the class of the sidekiq worker
34
34
  # @option item [Float] :at the unix time the job is scheduled at
35
35
  def initialize(item)
36
- @item = item
37
- @worker_class = item[CLASS]
36
+ @item = item
37
+ self.job_class = item[CLASS]
38
38
  end
39
39
 
40
40
  #
@@ -67,11 +67,11 @@ module SidekiqUniqueJobs
67
67
  #
68
68
  def calculate
69
69
  ttl = item[LOCK_TTL]
70
- ttl ||= worker_options[LOCK_TTL]
70
+ ttl ||= job_options[LOCK_TTL]
71
71
  ttl ||= item[LOCK_EXPIRATION] # TODO: Deprecate at some point
72
- ttl ||= worker_options[LOCK_EXPIRATION] # TODO: Deprecate at some point
72
+ ttl ||= job_options[LOCK_EXPIRATION] # TODO: Deprecate at some point
73
73
  ttl ||= SidekiqUniqueJobs.config.lock_ttl
74
- ttl && ttl.to_i + time_until_scheduled
74
+ ttl && (ttl.to_i + time_until_scheduled)
75
75
  end
76
76
  end
77
77
  end
@@ -188,18 +188,18 @@ module SidekiqUniqueJobs
188
188
  # @yieldparam [string] job_id the sidekiq JID
189
189
  # @yieldreturn [void] whatever the calling block returns
190
190
  def lock!(conn, primed_method, wait = nil)
191
- return yield job_id if locked?(conn)
191
+ return yield if locked?(conn)
192
192
 
193
193
  enqueue(conn) do |queued_jid|
194
- reflect(:debug, item, queued_jid)
194
+ reflect(:debug, :queued, item, queued_jid)
195
195
 
196
196
  primed_method.call(conn, wait) do |primed_jid|
197
197
  reflect(:debug, :primed, item, primed_jid)
198
-
199
198
  locked_jid = call_script(:lock, key.to_a, argv, conn)
199
+
200
200
  if locked_jid
201
201
  reflect(:debug, :locked, item, locked_jid)
202
- return yield job_id
202
+ return yield
203
203
  end
204
204
  end
205
205
  end
@@ -328,6 +328,7 @@ module SidekiqUniqueJobs
328
328
  end
329
329
 
330
330
  def add_drift(val)
331
+ val = val.to_f
331
332
  val + drift(val)
332
333
  end
333
334
 
@@ -92,9 +92,18 @@ module SidekiqUniqueJobs
92
92
  def log_fatal(message_or_exception = nil, item = nil, &block)
93
93
  message = build_message(message_or_exception, item)
94
94
  logger.fatal(message, &block)
95
+
95
96
  nil
96
97
  end
97
98
 
99
+ #
100
+ # Build a log message
101
+ #
102
+ # @param [String, Exception] message_or_exception an entry to log
103
+ # @param [Hash] item the sidekiq job hash
104
+ #
105
+ # @return [String] a complete log entry
106
+ #
98
107
  def build_message(message_or_exception, item = nil)
99
108
  return nil if message_or_exception.nil?
100
109
  return message_or_exception if item.nil?