sidekiq 6.1.1 → 6.5.7

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

Potentially problematic release.


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

Files changed (118) hide show
  1. checksums.yaml +4 -4
  2. data/Changes.md +230 -3
  3. data/LICENSE +3 -3
  4. data/README.md +10 -6
  5. data/bin/sidekiq +3 -3
  6. data/bin/sidekiqload +70 -66
  7. data/bin/sidekiqmon +1 -1
  8. data/lib/generators/sidekiq/job_generator.rb +57 -0
  9. data/lib/generators/sidekiq/templates/{worker.rb.erb → job.rb.erb} +2 -2
  10. data/lib/generators/sidekiq/templates/{worker_spec.rb.erb → job_spec.rb.erb} +1 -1
  11. data/lib/generators/sidekiq/templates/{worker_test.rb.erb → job_test.rb.erb} +1 -1
  12. data/lib/sidekiq/api.rb +335 -146
  13. data/lib/sidekiq/cli.rb +74 -41
  14. data/lib/sidekiq/client.rb +48 -72
  15. data/lib/sidekiq/{util.rb → component.rb} +12 -14
  16. data/lib/sidekiq/delay.rb +3 -1
  17. data/lib/sidekiq/extensions/action_mailer.rb +3 -2
  18. data/lib/sidekiq/extensions/active_record.rb +1 -1
  19. data/lib/sidekiq/extensions/generic_proxy.rb +4 -2
  20. data/lib/sidekiq/fetch.rb +31 -20
  21. data/lib/sidekiq/job.rb +13 -0
  22. data/lib/sidekiq/job_logger.rb +16 -28
  23. data/lib/sidekiq/job_retry.rb +79 -59
  24. data/lib/sidekiq/job_util.rb +71 -0
  25. data/lib/sidekiq/launcher.rb +126 -65
  26. data/lib/sidekiq/logger.rb +11 -20
  27. data/lib/sidekiq/manager.rb +35 -34
  28. data/lib/sidekiq/metrics/deploy.rb +47 -0
  29. data/lib/sidekiq/metrics/query.rb +153 -0
  30. data/lib/sidekiq/metrics/shared.rb +94 -0
  31. data/lib/sidekiq/metrics/tracking.rb +134 -0
  32. data/lib/sidekiq/middleware/chain.rb +88 -42
  33. data/lib/sidekiq/middleware/current_attributes.rb +63 -0
  34. data/lib/sidekiq/middleware/i18n.rb +6 -4
  35. data/lib/sidekiq/middleware/modules.rb +21 -0
  36. data/lib/sidekiq/monitor.rb +1 -1
  37. data/lib/sidekiq/paginator.rb +8 -8
  38. data/lib/sidekiq/processor.rb +47 -41
  39. data/lib/sidekiq/rails.rb +22 -4
  40. data/lib/sidekiq/redis_client_adapter.rb +154 -0
  41. data/lib/sidekiq/redis_connection.rb +84 -55
  42. data/lib/sidekiq/ring_buffer.rb +29 -0
  43. data/lib/sidekiq/scheduled.rb +96 -32
  44. data/lib/sidekiq/testing/inline.rb +4 -4
  45. data/lib/sidekiq/testing.rb +38 -39
  46. data/lib/sidekiq/transaction_aware_client.rb +45 -0
  47. data/lib/sidekiq/version.rb +1 -1
  48. data/lib/sidekiq/web/action.rb +3 -3
  49. data/lib/sidekiq/web/application.rb +38 -16
  50. data/lib/sidekiq/web/csrf_protection.rb +32 -5
  51. data/lib/sidekiq/web/helpers.rb +60 -28
  52. data/lib/sidekiq/web/router.rb +4 -1
  53. data/lib/sidekiq/web.rb +38 -78
  54. data/lib/sidekiq/worker.rb +140 -14
  55. data/lib/sidekiq.rb +114 -31
  56. data/sidekiq.gemspec +12 -4
  57. data/web/assets/images/apple-touch-icon.png +0 -0
  58. data/web/assets/javascripts/application.js +113 -60
  59. data/web/assets/javascripts/chart.min.js +13 -0
  60. data/web/assets/javascripts/chartjs-plugin-annotation.min.js +7 -0
  61. data/web/assets/javascripts/dashboard.js +50 -67
  62. data/web/assets/javascripts/graph.js +16 -0
  63. data/web/assets/javascripts/metrics.js +262 -0
  64. data/web/assets/stylesheets/application-dark.css +61 -51
  65. data/web/assets/stylesheets/application-rtl.css +0 -4
  66. data/web/assets/stylesheets/application.css +84 -243
  67. data/web/locales/ar.yml +8 -2
  68. data/web/locales/el.yml +43 -19
  69. data/web/locales/en.yml +11 -1
  70. data/web/locales/es.yml +18 -2
  71. data/web/locales/fr.yml +8 -1
  72. data/web/locales/ja.yml +10 -0
  73. data/web/locales/lt.yml +1 -1
  74. data/web/locales/pt-br.yml +27 -9
  75. data/web/locales/ru.yml +4 -0
  76. data/web/locales/zh-cn.yml +36 -11
  77. data/web/locales/zh-tw.yml +32 -7
  78. data/web/views/_footer.erb +1 -1
  79. data/web/views/_job_info.erb +1 -1
  80. data/web/views/_nav.erb +1 -1
  81. data/web/views/_poll_link.erb +2 -5
  82. data/web/views/_summary.erb +7 -7
  83. data/web/views/busy.erb +52 -21
  84. data/web/views/dashboard.erb +23 -14
  85. data/web/views/dead.erb +1 -1
  86. data/web/views/layout.erb +2 -1
  87. data/web/views/metrics.erb +69 -0
  88. data/web/views/metrics_for_job.erb +87 -0
  89. data/web/views/morgue.erb +6 -6
  90. data/web/views/queue.erb +15 -11
  91. data/web/views/queues.erb +4 -4
  92. data/web/views/retries.erb +7 -7
  93. data/web/views/retry.erb +1 -1
  94. data/web/views/scheduled.erb +1 -1
  95. metadata +46 -39
  96. data/.circleci/config.yml +0 -71
  97. data/.github/contributing.md +0 -32
  98. data/.github/issue_template.md +0 -11
  99. data/.gitignore +0 -13
  100. data/.standard.yml +0 -20
  101. data/3.0-Upgrade.md +0 -70
  102. data/4.0-Upgrade.md +0 -53
  103. data/5.0-Upgrade.md +0 -56
  104. data/6.0-Upgrade.md +0 -72
  105. data/COMM-LICENSE +0 -97
  106. data/Ent-2.0-Upgrade.md +0 -37
  107. data/Ent-Changes.md +0 -275
  108. data/Gemfile +0 -24
  109. data/Gemfile.lock +0 -208
  110. data/Pro-2.0-Upgrade.md +0 -138
  111. data/Pro-3.0-Upgrade.md +0 -44
  112. data/Pro-4.0-Upgrade.md +0 -35
  113. data/Pro-5.0-Upgrade.md +0 -25
  114. data/Pro-Changes.md +0 -795
  115. data/Rakefile +0 -10
  116. data/code_of_conduct.md +0 -50
  117. data/lib/generators/sidekiq/worker_generator.rb +0 -57
  118. data/lib/sidekiq/exception_handler.rb +0 -27
@@ -9,6 +9,7 @@ module Sidekiq
9
9
  #
10
10
  # class HardWorker
11
11
  # include Sidekiq::Worker
12
+ # sidekiq_options queue: 'critical', retry: 5
12
13
  #
13
14
  # def perform(*args)
14
15
  # # do some work
@@ -20,6 +21,26 @@ module Sidekiq
20
21
  # HardWorker.perform_async(1, 2, 3)
21
22
  #
22
23
  # Note that perform_async is a class method, perform is an instance method.
24
+ #
25
+ # Sidekiq::Worker also includes several APIs to provide compatibility with
26
+ # ActiveJob.
27
+ #
28
+ # class SomeWorker
29
+ # include Sidekiq::Worker
30
+ # queue_as :critical
31
+ #
32
+ # def perform(...)
33
+ # end
34
+ # end
35
+ #
36
+ # SomeWorker.set(wait_until: 1.hour).perform_async(123)
37
+ #
38
+ # Note that arguments passed to the job must still obey Sidekiq's
39
+ # best practice for simple, JSON-native data types. Sidekiq will not
40
+ # implement ActiveJob's more complex argument serialization. For
41
+ # this reason, we don't implement `perform_later` as our call semantics
42
+ # are very different.
43
+ #
23
44
  module Worker
24
45
  ##
25
46
  # The Options module is extracted so we can include it in ActiveJob::Base
@@ -61,7 +82,7 @@ module Sidekiq
61
82
  end
62
83
 
63
84
  def get_sidekiq_options # :nodoc:
64
- self.sidekiq_options_hash ||= Sidekiq.default_worker_options
85
+ self.sidekiq_options_hash ||= Sidekiq.default_job_options
65
86
  end
66
87
 
67
88
  def sidekiq_class_attribute(*attrs)
@@ -150,33 +171,97 @@ module Sidekiq
150
171
  # SomeWorker.set(queue: 'foo').perform_async(....)
151
172
  #
152
173
  class Setter
174
+ include Sidekiq::JobUtil
175
+
153
176
  def initialize(klass, opts)
154
177
  @klass = klass
155
- @opts = opts
178
+ # NB: the internal hash always has stringified keys
179
+ @opts = opts.transform_keys(&:to_s)
180
+
181
+ # ActiveJob compatibility
182
+ interval = @opts.delete("wait_until") || @opts.delete("wait")
183
+ at(interval) if interval
156
184
  end
157
185
 
158
186
  def set(options)
159
- @opts.merge!(options)
187
+ hash = options.transform_keys(&:to_s)
188
+ interval = hash.delete("wait_until") || @opts.delete("wait")
189
+ @opts.merge!(hash)
190
+ at(interval) if interval
160
191
  self
161
192
  end
162
193
 
163
194
  def perform_async(*args)
164
- @klass.client_push(@opts.merge("args" => args, "class" => @klass))
195
+ if @opts["sync"] == true
196
+ perform_inline(*args)
197
+ else
198
+ @klass.client_push(@opts.merge("args" => args, "class" => @klass))
199
+ end
200
+ end
201
+
202
+ # Explicit inline execution of a job. Returns nil if the job did not
203
+ # execute, true otherwise.
204
+ def perform_inline(*args)
205
+ raw = @opts.merge("args" => args, "class" => @klass)
206
+
207
+ # validate and normalize payload
208
+ item = normalize_item(raw)
209
+ queue = item["queue"]
210
+
211
+ # run client-side middleware
212
+ result = Sidekiq.client_middleware.invoke(item["class"], item, queue, Sidekiq.redis_pool) do
213
+ item
214
+ end
215
+ return nil unless result
216
+
217
+ # round-trip the payload via JSON
218
+ msg = Sidekiq.load_json(Sidekiq.dump_json(item))
219
+
220
+ # prepare the job instance
221
+ klass = msg["class"].constantize
222
+ job = klass.new
223
+ job.jid = msg["jid"]
224
+ job.bid = msg["bid"] if job.respond_to?(:bid)
225
+
226
+ # run the job through server-side middleware
227
+ result = Sidekiq.server_middleware.invoke(job, msg, msg["queue"]) do
228
+ # perform it
229
+ job.perform(*msg["args"])
230
+ true
231
+ end
232
+ return nil unless result
233
+ # jobs do not return a result. they should store any
234
+ # modified state.
235
+ true
236
+ end
237
+ alias_method :perform_sync, :perform_inline
238
+
239
+ def perform_bulk(args, batch_size: 1_000)
240
+ client = @klass.build_client
241
+ result = args.each_slice(batch_size).flat_map do |slice|
242
+ client.push_bulk(@opts.merge("class" => @klass, "args" => slice))
243
+ end
244
+
245
+ result.is_a?(Enumerator::Lazy) ? result.force : result
165
246
  end
166
247
 
167
248
  # +interval+ must be a timestamp, numeric or something that acts
168
249
  # numeric (like an activesupport time interval).
169
250
  def perform_in(interval, *args)
251
+ at(interval).perform_async(*args)
252
+ end
253
+ alias_method :perform_at, :perform_in
254
+
255
+ private
256
+
257
+ def at(interval)
170
258
  int = interval.to_f
171
259
  now = Time.now.to_f
172
260
  ts = (int < 1_000_000_000 ? now + int : int)
173
-
174
- payload = @opts.merge("class" => @klass, "args" => args)
175
261
  # Optimization to enqueue something now that is scheduled to go out now or in the past
176
- payload["at"] = ts if ts > now
177
- @klass.client_push(payload)
262
+ @opts["at"] = ts if ts > now
263
+ self
178
264
  end
179
- alias_method :perform_at, :perform_in
180
265
  end
181
266
 
182
267
  module ClassMethods
@@ -192,12 +277,46 @@ module Sidekiq
192
277
  raise ArgumentError, "Do not call .delay_until on a Sidekiq::Worker class, call .perform_at"
193
278
  end
194
279
 
280
+ def queue_as(q)
281
+ sidekiq_options("queue" => q.to_s)
282
+ end
283
+
195
284
  def set(options)
196
285
  Setter.new(self, options)
197
286
  end
198
287
 
199
288
  def perform_async(*args)
200
- client_push("class" => self, "args" => args)
289
+ Setter.new(self, {}).perform_async(*args)
290
+ end
291
+
292
+ # Inline execution of job's perform method after passing through Sidekiq.client_middleware and Sidekiq.server_middleware
293
+ def perform_inline(*args)
294
+ Setter.new(self, {}).perform_inline(*args)
295
+ end
296
+ alias_method :perform_sync, :perform_inline
297
+
298
+ ##
299
+ # Push a large number of jobs to Redis, while limiting the batch of
300
+ # each job payload to 1,000. This method helps cut down on the number
301
+ # of round trips to Redis, which can increase the performance of enqueueing
302
+ # large numbers of jobs.
303
+ #
304
+ # +items+ must be an Array of Arrays.
305
+ #
306
+ # For finer-grained control, use `Sidekiq::Client.push_bulk` directly.
307
+ #
308
+ # Example (3 Redis round trips):
309
+ #
310
+ # SomeWorker.perform_async(1)
311
+ # SomeWorker.perform_async(2)
312
+ # SomeWorker.perform_async(3)
313
+ #
314
+ # Would instead become (1 Redis round trip):
315
+ #
316
+ # SomeWorker.perform_bulk([[1], [2], [3]])
317
+ #
318
+ def perform_bulk(*args, **kwargs)
319
+ Setter.new(self, {}).perform_bulk(*args, **kwargs)
201
320
  end
202
321
 
203
322
  # +interval+ must be a timestamp, numeric or something that acts
@@ -221,7 +340,7 @@ module Sidekiq
221
340
  # Legal options:
222
341
  #
223
342
  # queue - use a named queue for this Worker, default 'default'
224
- # retry - enable the RetryJobs middleware for this Worker, *true* to use the default
343
+ # retry - enable retries via JobRetry, *true* to use the default
225
344
  # or *Integer* count
226
345
  # backtrace - whether to save any error backtrace in the retry payload to display in web UI,
227
346
  # can be true, false or an integer number of lines to save, default *false*
@@ -229,15 +348,22 @@ module Sidekiq
229
348
  #
230
349
  # In practice, any option is allowed. This is the main mechanism to configure the
231
350
  # options for a specific job.
351
+ #
352
+ # These options will be saved into the serialized job when enqueued by
353
+ # the client.
232
354
  def sidekiq_options(opts = {})
233
355
  super
234
356
  end
235
357
 
236
358
  def client_push(item) # :nodoc:
237
- pool = Thread.current[:sidekiq_via_pool] || get_sidekiq_options["pool"] || Sidekiq.redis_pool
238
- stringified_item = item.transform_keys(&:to_s)
359
+ raise ArgumentError, "Job payloads should contain no Symbols: #{item}" if item.any? { |k, v| k.is_a?(::Symbol) }
360
+ build_client.push(item)
361
+ end
239
362
 
240
- Sidekiq::Client.new(pool).push(stringified_item)
363
+ def build_client # :nodoc:
364
+ pool = Thread.current[:sidekiq_via_pool] || get_sidekiq_options["pool"] || Sidekiq.redis_pool
365
+ client_class = get_sidekiq_options["client_class"] || Sidekiq::Client
366
+ client_class.new(pool)
241
367
  end
242
368
  end
243
369
  end
data/lib/sidekiq.rb CHANGED
@@ -5,7 +5,9 @@ fail "Sidekiq #{Sidekiq::VERSION} does not support Ruby versions below 2.5.0." i
5
5
 
6
6
  require "sidekiq/logger"
7
7
  require "sidekiq/client"
8
+ require "sidekiq/transaction_aware_client"
8
9
  require "sidekiq/worker"
10
+ require "sidekiq/job"
9
11
  require "sidekiq/redis_connection"
10
12
  require "sidekiq/delay"
11
13
 
@@ -25,24 +27,23 @@ module Sidekiq
25
27
  timeout: 25,
26
28
  poll_interval_average: nil,
27
29
  average_scheduled_poll_interval: 5,
30
+ on_complex_arguments: :warn,
28
31
  error_handlers: [],
29
32
  death_handlers: [],
30
33
  lifecycle_events: {
31
34
  startup: [],
32
35
  quiet: [],
33
36
  shutdown: [],
34
- heartbeat: []
37
+ # triggers when we fire the first heartbeat on startup OR repairing a network partition
38
+ heartbeat: [],
39
+ # triggers on EVERY heartbeat call, every 10 seconds
40
+ beat: []
35
41
  },
36
42
  dead_max_jobs: 10_000,
37
43
  dead_timeout_in_seconds: 180 * 24 * 60 * 60, # 6 months
38
44
  reloader: proc { |&block| block.call }
39
45
  }
40
46
 
41
- DEFAULT_WORKER_OPTIONS = {
42
- "retry" => true,
43
- "queue" => "default"
44
- }
45
-
46
47
  FAKE_INFO = {
47
48
  "redis_version" => "9.9.9",
48
49
  "uptime_in_days" => "9999",
@@ -55,19 +56,84 @@ module Sidekiq
55
56
  puts "Calm down, yo."
56
57
  end
57
58
 
59
+ # config.concurrency = 5
60
+ def self.concurrency=(val)
61
+ self[:concurrency] = Integer(val)
62
+ end
63
+
64
+ # config.queues = %w( high default low ) # strict
65
+ # config.queues = %w( high,3 default,2 low,1 ) # weighted
66
+ # config.queues = %w( feature1,1 feature2,1 feature3,1 ) # random
67
+ #
68
+ # With weighted priority, queue will be checked first (weight / total) of the time.
69
+ # high will be checked first (3/6) or 50% of the time.
70
+ # I'd recommend setting weights between 1-10. Weights in the hundreds or thousands
71
+ # are ridiculous and unnecessarily expensive. You can get random queue ordering
72
+ # by explicitly setting all weights to 1.
73
+ def self.queues=(val)
74
+ self[:queues] = Array(val).each_with_object([]) do |qstr, memo|
75
+ name, weight = qstr.split(",")
76
+ self[:strict] = false if weight.to_i > 0
77
+ [weight.to_i, 1].max.times do
78
+ memo << name
79
+ end
80
+ end
81
+ end
82
+
83
+ ### Private APIs
84
+ def self.default_error_handler(ex, ctx)
85
+ logger.warn(dump_json(ctx)) unless ctx.empty?
86
+ logger.warn("#{ex.class.name}: #{ex.message}")
87
+ logger.warn(ex.backtrace.join("\n")) unless ex.backtrace.nil?
88
+ end
89
+
90
+ # DEFAULT_ERROR_HANDLER is a constant that allows the default error handler to
91
+ # be referenced. It must be defined here, after the default_error_handler
92
+ # method is defined.
93
+ DEFAULT_ERROR_HANDLER = method(:default_error_handler)
94
+
95
+ @config = DEFAULTS.dup
58
96
  def self.options
59
- @options ||= DEFAULTS.dup
97
+ logger.warn "`config.options[:key] = value` is deprecated, use `config[:key] = value`: #{caller(1..2)}"
98
+ @config
60
99
  end
61
100
 
62
101
  def self.options=(opts)
63
- @options = opts
102
+ logger.warn "config.options = hash` is deprecated, use `config.merge!(hash)`: #{caller(1..2)}"
103
+ @config = opts
104
+ end
105
+
106
+ def self.[](key)
107
+ @config[key]
108
+ end
109
+
110
+ def self.[]=(key, val)
111
+ @config[key] = val
64
112
  end
65
113
 
114
+ def self.merge!(hash)
115
+ @config.merge!(hash)
116
+ end
117
+
118
+ def self.fetch(*args, &block)
119
+ @config.fetch(*args, &block)
120
+ end
121
+
122
+ def self.handle_exception(ex, ctx = {})
123
+ self[:error_handlers].each do |handler|
124
+ handler.call(ex, ctx)
125
+ rescue => ex
126
+ logger.error "!!! ERROR HANDLER THREW AN ERROR !!!"
127
+ logger.error ex
128
+ logger.error ex.backtrace.join("\n") unless ex.backtrace.nil?
129
+ end
130
+ end
131
+ ###
132
+
66
133
  ##
67
134
  # Configuration for Sidekiq server, use like:
68
135
  #
69
136
  # Sidekiq.configure_server do |config|
70
- # config.redis = { :namespace => 'myapp', :size => 25, :url => 'redis://myhost:8877/0' }
71
137
  # config.server_middleware do |chain|
72
138
  # chain.add MyServerHook
73
139
  # end
@@ -80,7 +146,7 @@ module Sidekiq
80
146
  # Configuration for Sidekiq client, use like:
81
147
  #
82
148
  # Sidekiq.configure_client do |config|
83
- # config.redis = { :namespace => 'myapp', :size => 1, :url => 'redis://myhost:8877/0' }
149
+ # config.redis = { size: 1, url: 'redis://myhost:8877/0' }
84
150
  # end
85
151
  def self.configure_client
86
152
  yield self unless server?
@@ -96,11 +162,13 @@ module Sidekiq
96
162
  retryable = true
97
163
  begin
98
164
  yield conn
99
- rescue Redis::BaseError => ex
165
+ rescue RedisConnection.adapter::BaseError => ex
100
166
  # 2550 Failover can cause the server to become a replica, need
101
167
  # to disconnect and reopen the socket to get back to the primary.
102
168
  # 4495 Use the same logic if we have a "Not enough replicas" error from the primary
103
- if retryable && ex.message =~ /READONLY|NOREPLICAS/
169
+ # 4985 Use the same logic when a blocking command is force-unblocked
170
+ # The same retry logic is also used in client.rb
171
+ if retryable && ex.message =~ /READONLY|NOREPLICAS|UNBLOCKED/
104
172
  conn.disconnect!
105
173
  retryable = false
106
174
  retry
@@ -119,7 +187,7 @@ module Sidekiq
119
187
  else
120
188
  conn.info
121
189
  end
122
- rescue Redis::CommandError => ex
190
+ rescue RedisConnection.adapter::CommandError => ex
123
191
  # 2850 return fake version when INFO command has (probably) been renamed
124
192
  raise unless /unknown command/.match?(ex.message)
125
193
  FAKE_INFO
@@ -127,19 +195,19 @@ module Sidekiq
127
195
  end
128
196
 
129
197
  def self.redis_pool
130
- @redis ||= Sidekiq::RedisConnection.create
198
+ @redis ||= RedisConnection.create
131
199
  end
132
200
 
133
201
  def self.redis=(hash)
134
202
  @redis = if hash.is_a?(ConnectionPool)
135
203
  hash
136
204
  else
137
- Sidekiq::RedisConnection.create(hash)
205
+ RedisConnection.create(hash)
138
206
  end
139
207
  end
140
208
 
141
209
  def self.client_middleware
142
- @client_chain ||= Middleware::Chain.new
210
+ @client_chain ||= Middleware::Chain.new(self)
143
211
  yield @client_chain if block_given?
144
212
  @client_chain
145
213
  end
@@ -151,16 +219,23 @@ module Sidekiq
151
219
  end
152
220
 
153
221
  def self.default_server_middleware
154
- Middleware::Chain.new
222
+ Middleware::Chain.new(self)
155
223
  end
156
224
 
157
- def self.default_worker_options=(hash)
158
- # stringify
159
- @default_worker_options = default_worker_options.merge(hash.transform_keys(&:to_s))
225
+ def self.default_worker_options=(hash) # deprecated
226
+ @default_job_options = default_job_options.merge(hash.transform_keys(&:to_s))
160
227
  end
161
228
 
162
- def self.default_worker_options
163
- defined?(@default_worker_options) ? @default_worker_options : DEFAULT_WORKER_OPTIONS
229
+ def self.default_job_options=(hash)
230
+ @default_job_options = default_job_options.merge(hash.transform_keys(&:to_s))
231
+ end
232
+
233
+ def self.default_worker_options # deprecated
234
+ @default_job_options ||= {"retry" => true, "queue" => "default"}
235
+ end
236
+
237
+ def self.default_job_options
238
+ @default_job_options ||= {"retry" => true, "queue" => "default"}
164
239
  end
165
240
 
166
241
  ##
@@ -173,7 +248,7 @@ module Sidekiq
173
248
  # end
174
249
  # end
175
250
  def self.death_handlers
176
- options[:death_handlers]
251
+ self[:death_handlers]
177
252
  end
178
253
 
179
254
  def self.load_json(string)
@@ -198,7 +273,7 @@ module Sidekiq
198
273
  end
199
274
 
200
275
  def self.logger
201
- @logger ||= Sidekiq::Logger.new(STDOUT, level: Logger::INFO)
276
+ @logger ||= Sidekiq::Logger.new($stdout, level: :info)
202
277
  end
203
278
 
204
279
  def self.logger=(logger)
@@ -216,13 +291,17 @@ module Sidekiq
216
291
  defined?(Sidekiq::Pro)
217
292
  end
218
293
 
294
+ def self.ent?
295
+ defined?(Sidekiq::Enterprise)
296
+ end
297
+
219
298
  # How frequently Redis should be checked by a random Sidekiq process for
220
299
  # scheduled and retriable jobs. Each individual process will take turns by
221
300
  # waiting some multiple of this value.
222
301
  #
223
302
  # See sidekiq/scheduled.rb for an in-depth explanation of this value
224
303
  def self.average_scheduled_poll_interval=(interval)
225
- options[:average_scheduled_poll_interval] = interval
304
+ self[:average_scheduled_poll_interval] = interval
226
305
  end
227
306
 
228
307
  # Register a proc to handle any error which occurs within the Sidekiq process.
@@ -233,7 +312,7 @@ module Sidekiq
233
312
  #
234
313
  # The default error handler logs errors to Sidekiq.logger.
235
314
  def self.error_handlers
236
- options[:error_handlers]
315
+ self[:error_handlers]
237
316
  end
238
317
 
239
318
  # Register a block to run at a point in the Sidekiq lifecycle.
@@ -246,16 +325,20 @@ module Sidekiq
246
325
  # end
247
326
  def self.on(event, &block)
248
327
  raise ArgumentError, "Symbols only please: #{event}" unless event.is_a?(Symbol)
249
- raise ArgumentError, "Invalid event name: #{event}" unless options[:lifecycle_events].key?(event)
250
- options[:lifecycle_events][event] << block
328
+ raise ArgumentError, "Invalid event name: #{event}" unless self[:lifecycle_events].key?(event)
329
+ self[:lifecycle_events][event] << block
330
+ end
331
+
332
+ def self.strict_args!(mode = :raise)
333
+ self[:on_complex_arguments] = mode
251
334
  end
252
335
 
253
- # We are shutting down Sidekiq but what about workers that
336
+ # We are shutting down Sidekiq but what about threads that
254
337
  # are working on some long job? This error is
255
- # raised in workers that have not finished within the hard
338
+ # raised in jobs that have not finished within the hard
256
339
  # timeout limit. This is needed to rollback db transactions,
257
340
  # otherwise Ruby's Thread#kill will commit. See #377.
258
- # DO NOT RESCUE THIS ERROR IN YOUR WORKERS
341
+ # DO NOT RESCUE THIS ERROR IN YOUR JOBS
259
342
  class Shutdown < Interrupt; end
260
343
  end
261
344
 
data/sidekiq.gemspec CHANGED
@@ -5,16 +5,24 @@ Gem::Specification.new do |gem|
5
5
  gem.email = ["mperham@gmail.com"]
6
6
  gem.summary = "Simple, efficient background processing for Ruby"
7
7
  gem.description = "Simple, efficient background processing for Ruby."
8
- gem.homepage = "http://sidekiq.org"
8
+ gem.homepage = "https://sidekiq.org"
9
9
  gem.license = "LGPL-3.0"
10
10
 
11
11
  gem.executables = ["sidekiq", "sidekiqmon"]
12
- gem.files = `git ls-files | grep -Ev '^(test|myapp|examples)'`.split("\n")
12
+ gem.files = ["sidekiq.gemspec", "README.md", "Changes.md", "LICENSE"] + `git ls-files | grep -E '^(bin|lib|web)'`.split("\n")
13
13
  gem.name = "sidekiq"
14
14
  gem.version = Sidekiq::VERSION
15
15
  gem.required_ruby_version = ">= 2.5.0"
16
16
 
17
- gem.add_dependency "redis", ">= 4.2.0"
18
- gem.add_dependency "connection_pool", ">= 2.2.2"
17
+ gem.metadata = {
18
+ "homepage_uri" => "https://sidekiq.org",
19
+ "bug_tracker_uri" => "https://github.com/mperham/sidekiq/issues",
20
+ "documentation_uri" => "https://github.com/mperham/sidekiq/wiki",
21
+ "changelog_uri" => "https://github.com/mperham/sidekiq/blob/main/Changes.md",
22
+ "source_code_uri" => "https://github.com/mperham/sidekiq"
23
+ }
24
+
25
+ gem.add_dependency "redis", "<5", ">= 4.5.0"
26
+ gem.add_dependency "connection_pool", ">= 2.2.5"
19
27
  gem.add_dependency "rack", "~> 2.0"
20
28
  end