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.
- checksums.yaml +4 -4
- data/Changes.md +230 -3
- data/LICENSE +3 -3
- data/README.md +10 -6
- data/bin/sidekiq +3 -3
- data/bin/sidekiqload +70 -66
- data/bin/sidekiqmon +1 -1
- data/lib/generators/sidekiq/job_generator.rb +57 -0
- data/lib/generators/sidekiq/templates/{worker.rb.erb → job.rb.erb} +2 -2
- data/lib/generators/sidekiq/templates/{worker_spec.rb.erb → job_spec.rb.erb} +1 -1
- data/lib/generators/sidekiq/templates/{worker_test.rb.erb → job_test.rb.erb} +1 -1
- data/lib/sidekiq/api.rb +335 -146
- data/lib/sidekiq/cli.rb +74 -41
- data/lib/sidekiq/client.rb +48 -72
- data/lib/sidekiq/{util.rb → component.rb} +12 -14
- data/lib/sidekiq/delay.rb +3 -1
- data/lib/sidekiq/extensions/action_mailer.rb +3 -2
- data/lib/sidekiq/extensions/active_record.rb +1 -1
- data/lib/sidekiq/extensions/generic_proxy.rb +4 -2
- data/lib/sidekiq/fetch.rb +31 -20
- data/lib/sidekiq/job.rb +13 -0
- data/lib/sidekiq/job_logger.rb +16 -28
- data/lib/sidekiq/job_retry.rb +79 -59
- data/lib/sidekiq/job_util.rb +71 -0
- data/lib/sidekiq/launcher.rb +126 -65
- data/lib/sidekiq/logger.rb +11 -20
- data/lib/sidekiq/manager.rb +35 -34
- data/lib/sidekiq/metrics/deploy.rb +47 -0
- data/lib/sidekiq/metrics/query.rb +153 -0
- data/lib/sidekiq/metrics/shared.rb +94 -0
- data/lib/sidekiq/metrics/tracking.rb +134 -0
- data/lib/sidekiq/middleware/chain.rb +88 -42
- data/lib/sidekiq/middleware/current_attributes.rb +63 -0
- data/lib/sidekiq/middleware/i18n.rb +6 -4
- data/lib/sidekiq/middleware/modules.rb +21 -0
- data/lib/sidekiq/monitor.rb +1 -1
- data/lib/sidekiq/paginator.rb +8 -8
- data/lib/sidekiq/processor.rb +47 -41
- data/lib/sidekiq/rails.rb +22 -4
- data/lib/sidekiq/redis_client_adapter.rb +154 -0
- data/lib/sidekiq/redis_connection.rb +84 -55
- data/lib/sidekiq/ring_buffer.rb +29 -0
- data/lib/sidekiq/scheduled.rb +96 -32
- data/lib/sidekiq/testing/inline.rb +4 -4
- data/lib/sidekiq/testing.rb +38 -39
- data/lib/sidekiq/transaction_aware_client.rb +45 -0
- data/lib/sidekiq/version.rb +1 -1
- data/lib/sidekiq/web/action.rb +3 -3
- data/lib/sidekiq/web/application.rb +38 -16
- data/lib/sidekiq/web/csrf_protection.rb +32 -5
- data/lib/sidekiq/web/helpers.rb +60 -28
- data/lib/sidekiq/web/router.rb +4 -1
- data/lib/sidekiq/web.rb +38 -78
- data/lib/sidekiq/worker.rb +140 -14
- data/lib/sidekiq.rb +114 -31
- data/sidekiq.gemspec +12 -4
- data/web/assets/images/apple-touch-icon.png +0 -0
- data/web/assets/javascripts/application.js +113 -60
- data/web/assets/javascripts/chart.min.js +13 -0
- data/web/assets/javascripts/chartjs-plugin-annotation.min.js +7 -0
- data/web/assets/javascripts/dashboard.js +50 -67
- data/web/assets/javascripts/graph.js +16 -0
- data/web/assets/javascripts/metrics.js +262 -0
- data/web/assets/stylesheets/application-dark.css +61 -51
- data/web/assets/stylesheets/application-rtl.css +0 -4
- data/web/assets/stylesheets/application.css +84 -243
- data/web/locales/ar.yml +8 -2
- data/web/locales/el.yml +43 -19
- data/web/locales/en.yml +11 -1
- data/web/locales/es.yml +18 -2
- data/web/locales/fr.yml +8 -1
- data/web/locales/ja.yml +10 -0
- data/web/locales/lt.yml +1 -1
- data/web/locales/pt-br.yml +27 -9
- data/web/locales/ru.yml +4 -0
- data/web/locales/zh-cn.yml +36 -11
- data/web/locales/zh-tw.yml +32 -7
- data/web/views/_footer.erb +1 -1
- data/web/views/_job_info.erb +1 -1
- data/web/views/_nav.erb +1 -1
- data/web/views/_poll_link.erb +2 -5
- data/web/views/_summary.erb +7 -7
- data/web/views/busy.erb +52 -21
- data/web/views/dashboard.erb +23 -14
- data/web/views/dead.erb +1 -1
- data/web/views/layout.erb +2 -1
- data/web/views/metrics.erb +69 -0
- data/web/views/metrics_for_job.erb +87 -0
- data/web/views/morgue.erb +6 -6
- data/web/views/queue.erb +15 -11
- data/web/views/queues.erb +4 -4
- data/web/views/retries.erb +7 -7
- data/web/views/retry.erb +1 -1
- data/web/views/scheduled.erb +1 -1
- metadata +46 -39
- data/.circleci/config.yml +0 -71
- data/.github/contributing.md +0 -32
- data/.github/issue_template.md +0 -11
- data/.gitignore +0 -13
- data/.standard.yml +0 -20
- data/3.0-Upgrade.md +0 -70
- data/4.0-Upgrade.md +0 -53
- data/5.0-Upgrade.md +0 -56
- data/6.0-Upgrade.md +0 -72
- data/COMM-LICENSE +0 -97
- data/Ent-2.0-Upgrade.md +0 -37
- data/Ent-Changes.md +0 -275
- data/Gemfile +0 -24
- data/Gemfile.lock +0 -208
- data/Pro-2.0-Upgrade.md +0 -138
- data/Pro-3.0-Upgrade.md +0 -44
- data/Pro-4.0-Upgrade.md +0 -35
- data/Pro-5.0-Upgrade.md +0 -25
- data/Pro-Changes.md +0 -795
- data/Rakefile +0 -10
- data/code_of_conduct.md +0 -50
- data/lib/generators/sidekiq/worker_generator.rb +0 -57
- data/lib/sidekiq/exception_handler.rb +0 -27
data/lib/sidekiq/worker.rb
CHANGED
@@ -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.
|
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
|
-
|
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
|
-
|
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
|
-
@
|
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
|
-
|
177
|
-
|
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
|
-
|
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
|
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
|
-
|
238
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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 = { :
|
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
|
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
|
-
|
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
|
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 ||=
|
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
|
-
|
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
|
-
|
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.
|
163
|
-
|
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
|
-
|
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(
|
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
|
-
|
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
|
-
|
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
|
250
|
-
|
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
|
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
|
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
|
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 = "
|
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 -
|
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.
|
18
|
-
|
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
|
Binary file
|