sidekiq 6.4.1 → 6.5.1
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 +47 -1
- data/README.md +1 -1
- data/bin/sidekiqload +16 -10
- data/lib/sidekiq/.DS_Store +0 -0
- data/lib/sidekiq/api.rb +73 -46
- data/lib/sidekiq/cli.rb +38 -37
- data/lib/sidekiq/client.rb +25 -26
- data/lib/sidekiq/component.rb +64 -0
- data/lib/sidekiq/delay.rb +1 -1
- data/lib/sidekiq/extensions/generic_proxy.rb +1 -1
- data/lib/sidekiq/fetch.rb +16 -14
- data/lib/sidekiq/job_retry.rb +29 -28
- data/lib/sidekiq/job_util.rb +15 -9
- data/lib/sidekiq/launcher.rb +31 -29
- data/lib/sidekiq/logger.rb +5 -19
- data/lib/sidekiq/manager.rb +28 -25
- data/lib/sidekiq/middleware/chain.rb +22 -13
- data/lib/sidekiq/middleware/current_attributes.rb +4 -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 +2 -2
- data/lib/sidekiq/processor.rb +38 -38
- data/lib/sidekiq/rails.rb +15 -8
- data/lib/sidekiq/redis_client_adapter.rb +154 -0
- data/lib/sidekiq/redis_connection.rb +81 -48
- data/lib/sidekiq/ring_buffer.rb +29 -0
- data/lib/sidekiq/scheduled.rb +11 -10
- data/lib/sidekiq/testing/inline.rb +4 -4
- data/lib/sidekiq/testing.rb +37 -36
- data/lib/sidekiq/transaction_aware_client.rb +45 -0
- data/lib/sidekiq/version.rb +1 -1
- data/lib/sidekiq/web/csrf_protection.rb +2 -2
- data/lib/sidekiq/web/helpers.rb +4 -4
- data/lib/sidekiq/worker.rb +18 -13
- data/lib/sidekiq.rb +97 -30
- data/web/assets/javascripts/application.js +58 -26
- data/web/assets/stylesheets/application.css +1 -2
- data/web/locales/pt-br.yml +27 -9
- data/web/views/_summary.erb +1 -1
- data/web/views/busy.erb +3 -3
- metadata +8 -4
- data/lib/sidekiq/exception_handler.rb +0 -27
- data/lib/sidekiq/util.rb +0 -108
data/lib/sidekiq/testing.rb
CHANGED
@@ -101,20 +101,20 @@ module Sidekiq
|
|
101
101
|
##
|
102
102
|
# The Queues class is only for testing the fake queue implementation.
|
103
103
|
# There are 2 data structures involved in tandem. This is due to the
|
104
|
-
# Rspec syntax of change(
|
104
|
+
# Rspec syntax of change(HardJob.jobs, :size). It keeps a reference
|
105
105
|
# to the array. Because the array was dervied from a filter of the total
|
106
106
|
# jobs enqueued, it appeared as though the array didn't change.
|
107
107
|
#
|
108
108
|
# To solve this, we'll keep 2 hashes containing the jobs. One with keys based
|
109
|
-
# on the queue, and another with keys of the
|
110
|
-
#
|
109
|
+
# on the queue, and another with keys of the job type, so the array for
|
110
|
+
# HardJob.jobs is a straight reference to a real array.
|
111
111
|
#
|
112
112
|
# Queue-based hash:
|
113
113
|
#
|
114
114
|
# {
|
115
115
|
# "default"=>[
|
116
116
|
# {
|
117
|
-
# "class"=>"TestTesting::
|
117
|
+
# "class"=>"TestTesting::HardJob",
|
118
118
|
# "args"=>[1, 2],
|
119
119
|
# "retry"=>true,
|
120
120
|
# "queue"=>"default",
|
@@ -124,12 +124,12 @@ module Sidekiq
|
|
124
124
|
# ]
|
125
125
|
# }
|
126
126
|
#
|
127
|
-
#
|
127
|
+
# Job-based hash:
|
128
128
|
#
|
129
129
|
# {
|
130
|
-
# "TestTesting::
|
130
|
+
# "TestTesting::HardJob"=>[
|
131
131
|
# {
|
132
|
-
# "class"=>"TestTesting::
|
132
|
+
# "class"=>"TestTesting::HardJob",
|
133
133
|
# "args"=>[1, 2],
|
134
134
|
# "retry"=>true,
|
135
135
|
# "queue"=>"default",
|
@@ -144,14 +144,14 @@ module Sidekiq
|
|
144
144
|
# require 'sidekiq/testing'
|
145
145
|
#
|
146
146
|
# assert_equal 0, Sidekiq::Queues["default"].size
|
147
|
-
#
|
147
|
+
# HardJob.perform_async(:something)
|
148
148
|
# assert_equal 1, Sidekiq::Queues["default"].size
|
149
149
|
# assert_equal :something, Sidekiq::Queues["default"].first['args'][0]
|
150
150
|
#
|
151
|
-
# You can also clear all
|
151
|
+
# You can also clear all jobs:
|
152
152
|
#
|
153
153
|
# assert_equal 0, Sidekiq::Queues["default"].size
|
154
|
-
#
|
154
|
+
# HardJob.perform_async(:something)
|
155
155
|
# Sidekiq::Queues.clear_all
|
156
156
|
# assert_equal 0, Sidekiq::Queues["default"].size
|
157
157
|
#
|
@@ -170,35 +170,36 @@ module Sidekiq
|
|
170
170
|
|
171
171
|
def push(queue, klass, job)
|
172
172
|
jobs_by_queue[queue] << job
|
173
|
-
|
173
|
+
jobs_by_class[klass] << job
|
174
174
|
end
|
175
175
|
|
176
176
|
def jobs_by_queue
|
177
177
|
@jobs_by_queue ||= Hash.new { |hash, key| hash[key] = [] }
|
178
178
|
end
|
179
179
|
|
180
|
-
def
|
181
|
-
@
|
180
|
+
def jobs_by_class
|
181
|
+
@jobs_by_class ||= Hash.new { |hash, key| hash[key] = [] }
|
182
182
|
end
|
183
|
+
alias_method :jobs_by_worker, :jobs_by_class
|
183
184
|
|
184
185
|
def delete_for(jid, queue, klass)
|
185
186
|
jobs_by_queue[queue.to_s].delete_if { |job| job["jid"] == jid }
|
186
|
-
|
187
|
+
jobs_by_class[klass].delete_if { |job| job["jid"] == jid }
|
187
188
|
end
|
188
189
|
|
189
190
|
def clear_for(queue, klass)
|
190
|
-
jobs_by_queue[queue].clear
|
191
|
-
|
191
|
+
jobs_by_queue[queue.to_s].clear
|
192
|
+
jobs_by_class[klass].clear
|
192
193
|
end
|
193
194
|
|
194
195
|
def clear_all
|
195
196
|
jobs_by_queue.clear
|
196
|
-
|
197
|
+
jobs_by_class.clear
|
197
198
|
end
|
198
199
|
end
|
199
200
|
end
|
200
201
|
|
201
|
-
module
|
202
|
+
module Job
|
202
203
|
##
|
203
204
|
# The Sidekiq testing infrastructure overrides perform_async
|
204
205
|
# so that it does not actually touch the network. Instead it
|
@@ -212,16 +213,16 @@ module Sidekiq
|
|
212
213
|
#
|
213
214
|
# require 'sidekiq/testing'
|
214
215
|
#
|
215
|
-
# assert_equal 0,
|
216
|
-
#
|
217
|
-
# assert_equal 1,
|
218
|
-
# assert_equal :something,
|
216
|
+
# assert_equal 0, HardJob.jobs.size
|
217
|
+
# HardJob.perform_async(:something)
|
218
|
+
# assert_equal 1, HardJob.jobs.size
|
219
|
+
# assert_equal :something, HardJob.jobs[0]['args'][0]
|
219
220
|
#
|
220
221
|
# assert_equal 0, Sidekiq::Extensions::DelayedMailer.jobs.size
|
221
222
|
# MyMailer.delay.send_welcome_email('foo@example.com')
|
222
223
|
# assert_equal 1, Sidekiq::Extensions::DelayedMailer.jobs.size
|
223
224
|
#
|
224
|
-
# You can also clear and drain all
|
225
|
+
# You can also clear and drain all job types:
|
225
226
|
#
|
226
227
|
# assert_equal 0, Sidekiq::Extensions::DelayedMailer.jobs.size
|
227
228
|
# assert_equal 0, Sidekiq::Extensions::DelayedModel.jobs.size
|
@@ -241,14 +242,14 @@ module Sidekiq
|
|
241
242
|
#
|
242
243
|
# RSpec.configure do |config|
|
243
244
|
# config.before(:each) do
|
244
|
-
# Sidekiq::
|
245
|
+
# Sidekiq::Job.clear_all
|
245
246
|
# end
|
246
247
|
# end
|
247
248
|
#
|
248
249
|
# or for acceptance testing, i.e. with cucumber:
|
249
250
|
#
|
250
251
|
# AfterStep do
|
251
|
-
# Sidekiq::
|
252
|
+
# Sidekiq::Job.drain_all
|
252
253
|
# end
|
253
254
|
#
|
254
255
|
# When I sign up as "foo@example.com"
|
@@ -262,7 +263,7 @@ module Sidekiq
|
|
262
263
|
|
263
264
|
# Jobs queued for this worker
|
264
265
|
def jobs
|
265
|
-
Queues.
|
266
|
+
Queues.jobs_by_class[to_s]
|
266
267
|
end
|
267
268
|
|
268
269
|
# Clear all jobs for this worker
|
@@ -288,11 +289,11 @@ module Sidekiq
|
|
288
289
|
end
|
289
290
|
|
290
291
|
def process_job(job)
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
Sidekiq::Testing.server_middleware.invoke(
|
295
|
-
execute_job(
|
292
|
+
inst = new
|
293
|
+
inst.jid = job["jid"]
|
294
|
+
inst.bid = job["bid"] if inst.respond_to?(:bid=)
|
295
|
+
Sidekiq::Testing.server_middleware.invoke(inst, job, job["queue"]) do
|
296
|
+
execute_job(inst, job["args"])
|
296
297
|
end
|
297
298
|
end
|
298
299
|
|
@@ -306,18 +307,18 @@ module Sidekiq
|
|
306
307
|
Queues.jobs_by_queue.values.flatten
|
307
308
|
end
|
308
309
|
|
309
|
-
# Clear all queued jobs
|
310
|
+
# Clear all queued jobs
|
310
311
|
def clear_all
|
311
312
|
Queues.clear_all
|
312
313
|
end
|
313
314
|
|
314
|
-
# Drain all queued jobs
|
315
|
+
# Drain (execute) all queued jobs
|
315
316
|
def drain_all
|
316
317
|
while jobs.any?
|
317
|
-
|
318
|
+
job_classes = jobs.map { |job| job["class"] }.uniq
|
318
319
|
|
319
|
-
|
320
|
-
Sidekiq::Testing.constantize(
|
320
|
+
job_classes.each do |job_class|
|
321
|
+
Sidekiq::Testing.constantize(job_class).drain
|
321
322
|
end
|
322
323
|
end
|
323
324
|
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "securerandom"
|
4
|
+
require "sidekiq/client"
|
5
|
+
|
6
|
+
module Sidekiq
|
7
|
+
class TransactionAwareClient
|
8
|
+
def initialize(redis_pool)
|
9
|
+
@redis_client = Client.new(redis_pool)
|
10
|
+
end
|
11
|
+
|
12
|
+
def push(item)
|
13
|
+
# pre-allocate the JID so we can return it immediately and
|
14
|
+
# save it to the database as part of the transaction.
|
15
|
+
item["jid"] ||= SecureRandom.hex(12)
|
16
|
+
AfterCommitEverywhere.after_commit { @redis_client.push(item) }
|
17
|
+
item["jid"]
|
18
|
+
end
|
19
|
+
|
20
|
+
##
|
21
|
+
# We don't provide transactionality for push_bulk because we don't want
|
22
|
+
# to hold potentially hundreds of thousands of job records in memory due to
|
23
|
+
# a long running enqueue process.
|
24
|
+
def push_bulk(items)
|
25
|
+
@redis_client.push_bulk(items)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
##
|
31
|
+
# Use `Sidekiq.transactional_push!` in your sidekiq.rb initializer
|
32
|
+
module Sidekiq
|
33
|
+
def self.transactional_push!
|
34
|
+
begin
|
35
|
+
require "after_commit_everywhere"
|
36
|
+
rescue LoadError
|
37
|
+
Sidekiq.logger.error("You need to add after_commit_everywhere to your Gemfile to use Sidekiq's transactional client")
|
38
|
+
raise
|
39
|
+
end
|
40
|
+
|
41
|
+
default_job_options["client_class"] = Sidekiq::TransactionAwareClient
|
42
|
+
Sidekiq::JobUtil::TRANSIENT_ATTRIBUTES << "client_class"
|
43
|
+
true
|
44
|
+
end
|
45
|
+
end
|
data/lib/sidekiq/version.rb
CHANGED
@@ -143,7 +143,7 @@ module Sidekiq
|
|
143
143
|
one_time_pad = SecureRandom.random_bytes(token.length)
|
144
144
|
encrypted_token = xor_byte_strings(one_time_pad, token)
|
145
145
|
masked_token = one_time_pad + encrypted_token
|
146
|
-
Base64.
|
146
|
+
Base64.urlsafe_encode64(masked_token)
|
147
147
|
end
|
148
148
|
|
149
149
|
# Essentially the inverse of +mask_token+.
|
@@ -169,7 +169,7 @@ module Sidekiq
|
|
169
169
|
end
|
170
170
|
|
171
171
|
def decode_token(token)
|
172
|
-
Base64.
|
172
|
+
Base64.urlsafe_decode64(token)
|
173
173
|
end
|
174
174
|
|
175
175
|
def xor_byte_strings(s1, s2)
|
data/lib/sidekiq/web/helpers.rb
CHANGED
@@ -140,8 +140,8 @@ module Sidekiq
|
|
140
140
|
params[:direction] == "asc" ? "↑" : "↓"
|
141
141
|
end
|
142
142
|
|
143
|
-
def
|
144
|
-
@
|
143
|
+
def workset
|
144
|
+
@work ||= Sidekiq::WorkSet.new
|
145
145
|
end
|
146
146
|
|
147
147
|
def processes
|
@@ -175,7 +175,7 @@ module Sidekiq
|
|
175
175
|
end
|
176
176
|
|
177
177
|
def current_status
|
178
|
-
|
178
|
+
workset.size == 0 ? "idle" : "active"
|
179
179
|
end
|
180
180
|
|
181
181
|
def relative_time(time)
|
@@ -301,7 +301,7 @@ module Sidekiq
|
|
301
301
|
end
|
302
302
|
|
303
303
|
def environment_title_prefix
|
304
|
-
environment = Sidekiq
|
304
|
+
environment = Sidekiq[:environment] || ENV["APP_ENV"] || ENV["RAILS_ENV"] || ENV["RACK_ENV"] || "development"
|
305
305
|
|
306
306
|
"[#{environment.upcase}] " unless environment == "production"
|
307
307
|
end
|
data/lib/sidekiq/worker.rb
CHANGED
@@ -82,7 +82,7 @@ module Sidekiq
|
|
82
82
|
end
|
83
83
|
|
84
84
|
def get_sidekiq_options # :nodoc:
|
85
|
-
self.sidekiq_options_hash ||= Sidekiq.
|
85
|
+
self.sidekiq_options_hash ||= Sidekiq.default_job_options
|
86
86
|
end
|
87
87
|
|
88
88
|
def sidekiq_class_attribute(*attrs)
|
@@ -175,16 +175,18 @@ module Sidekiq
|
|
175
175
|
|
176
176
|
def initialize(klass, opts)
|
177
177
|
@klass = klass
|
178
|
-
|
178
|
+
# NB: the internal hash always has stringified keys
|
179
|
+
@opts = opts.transform_keys(&:to_s)
|
179
180
|
|
180
181
|
# ActiveJob compatibility
|
181
|
-
interval = @opts.delete(
|
182
|
+
interval = @opts.delete("wait_until") || @opts.delete("wait")
|
182
183
|
at(interval) if interval
|
183
184
|
end
|
184
185
|
|
185
186
|
def set(options)
|
186
|
-
|
187
|
-
@opts.
|
187
|
+
hash = options.transform_keys(&:to_s)
|
188
|
+
interval = hash.delete("wait_until") || @opts.delete("wait")
|
189
|
+
@opts.merge!(hash)
|
188
190
|
at(interval) if interval
|
189
191
|
self
|
190
192
|
end
|
@@ -200,7 +202,7 @@ module Sidekiq
|
|
200
202
|
# Explicit inline execution of a job. Returns nil if the job did not
|
201
203
|
# execute, true otherwise.
|
202
204
|
def perform_inline(*args)
|
203
|
-
raw = @opts.merge("args" => args, "class" => @klass)
|
205
|
+
raw = @opts.merge("args" => args, "class" => @klass)
|
204
206
|
|
205
207
|
# validate and normalize payload
|
206
208
|
item = normalize_item(raw)
|
@@ -235,11 +237,9 @@ module Sidekiq
|
|
235
237
|
alias_method :perform_sync, :perform_inline
|
236
238
|
|
237
239
|
def perform_bulk(args, batch_size: 1_000)
|
238
|
-
|
239
|
-
pool = Thread.current[:sidekiq_via_pool] || @klass.get_sidekiq_options["pool"] || Sidekiq.redis_pool
|
240
|
-
client = Sidekiq::Client.new(pool)
|
240
|
+
client = @klass.build_client
|
241
241
|
result = args.each_slice(batch_size).flat_map do |slice|
|
242
|
-
client.push_bulk(
|
242
|
+
client.push_bulk(@opts.merge("class" => @klass, "args" => slice))
|
243
243
|
end
|
244
244
|
|
245
245
|
result.is_a?(Enumerator::Lazy) ? result.force : result
|
@@ -293,6 +293,7 @@ module Sidekiq
|
|
293
293
|
def perform_inline(*args)
|
294
294
|
Setter.new(self, {}).perform_inline(*args)
|
295
295
|
end
|
296
|
+
alias_method :perform_sync, :perform_inline
|
296
297
|
|
297
298
|
##
|
298
299
|
# Push a large number of jobs to Redis, while limiting the batch of
|
@@ -352,10 +353,14 @@ module Sidekiq
|
|
352
353
|
end
|
353
354
|
|
354
355
|
def client_push(item) # :nodoc:
|
355
|
-
|
356
|
-
|
356
|
+
raise ArgumentError, "Job payloads should contain no Symbols: #{item}" if item.any? { |k, v| k.is_a?(::Symbol) }
|
357
|
+
build_client.push(item)
|
358
|
+
end
|
357
359
|
|
358
|
-
|
360
|
+
def build_client # :nodoc:
|
361
|
+
pool = Thread.current[:sidekiq_via_pool] || get_sidekiq_options["pool"] || Sidekiq.redis_pool
|
362
|
+
client_class = get_sidekiq_options["client_class"] || Sidekiq::Client
|
363
|
+
client_class.new(pool)
|
359
364
|
end
|
360
365
|
end
|
361
366
|
end
|
data/lib/sidekiq.rb
CHANGED
@@ -5,6 +5,7 @@ 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"
|
9
10
|
require "sidekiq/job"
|
10
11
|
require "sidekiq/redis_connection"
|
@@ -40,11 +41,6 @@ module Sidekiq
|
|
40
41
|
reloader: proc { |&block| block.call }
|
41
42
|
}
|
42
43
|
|
43
|
-
DEFAULT_WORKER_OPTIONS = {
|
44
|
-
"retry" => true,
|
45
|
-
"queue" => "default"
|
46
|
-
}
|
47
|
-
|
48
44
|
FAKE_INFO = {
|
49
45
|
"redis_version" => "9.9.9",
|
50
46
|
"uptime_in_days" => "9999",
|
@@ -57,19 +53,79 @@ module Sidekiq
|
|
57
53
|
puts "Calm down, yo."
|
58
54
|
end
|
59
55
|
|
56
|
+
# config.concurrency = 5
|
57
|
+
def self.concurrency=(val)
|
58
|
+
self[:concurrency] = Integer(val)
|
59
|
+
end
|
60
|
+
|
61
|
+
# config.queues = %w( high default low ) # strict
|
62
|
+
# config.queues = %w( high,3 default,2 low,1 ) # weighted
|
63
|
+
# config.queues = %w( feature1,1 feature2,1 feature3,1 ) # random
|
64
|
+
#
|
65
|
+
# With weighted priority, queue will be checked first (weight / total) of the time.
|
66
|
+
# high will be checked first (3/6) or 50% of the time.
|
67
|
+
# I'd recommend setting weights between 1-10. Weights in the hundreds or thousands
|
68
|
+
# are ridiculous and unnecessarily expensive. You can get random queue ordering
|
69
|
+
# by explicitly setting all weights to 1.
|
70
|
+
def self.queues=(val)
|
71
|
+
self[:queues] = Array(val).each_with_object([]) do |qstr, memo|
|
72
|
+
name, weight = qstr.split(",")
|
73
|
+
self[:strict] = false if weight.to_i > 0
|
74
|
+
[weight.to_i, 1].max.times do
|
75
|
+
memo << name
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
### Private APIs
|
81
|
+
def self.default_error_handler(ex, ctx)
|
82
|
+
logger.warn(dump_json(ctx)) unless ctx.empty?
|
83
|
+
logger.warn("#{ex.class.name}: #{ex.message}")
|
84
|
+
logger.warn(ex.backtrace.join("\n")) unless ex.backtrace.nil?
|
85
|
+
end
|
86
|
+
|
87
|
+
@config = DEFAULTS.dup
|
60
88
|
def self.options
|
61
|
-
|
89
|
+
logger.warn "`config.options[:key] = value` is deprecated, use `config[:key] = value`: #{caller(1..2)}"
|
90
|
+
@config
|
62
91
|
end
|
63
92
|
|
64
93
|
def self.options=(opts)
|
65
|
-
|
94
|
+
logger.warn "config.options = hash` is deprecated, use `config.merge!(hash)`: #{caller(1..2)}"
|
95
|
+
@config = opts
|
96
|
+
end
|
97
|
+
|
98
|
+
def self.[](key)
|
99
|
+
@config[key]
|
100
|
+
end
|
101
|
+
|
102
|
+
def self.[]=(key, val)
|
103
|
+
@config[key] = val
|
104
|
+
end
|
105
|
+
|
106
|
+
def self.merge!(hash)
|
107
|
+
@config.merge!(hash)
|
108
|
+
end
|
109
|
+
|
110
|
+
def self.fetch(*args, &block)
|
111
|
+
@config.fetch(*args, &block)
|
112
|
+
end
|
113
|
+
|
114
|
+
def self.handle_exception(ex, ctx = {})
|
115
|
+
self[:error_handlers].each do |handler|
|
116
|
+
handler.call(ex, ctx)
|
117
|
+
rescue => ex
|
118
|
+
logger.error "!!! ERROR HANDLER THREW AN ERROR !!!"
|
119
|
+
logger.error ex
|
120
|
+
logger.error ex.backtrace.join("\n") unless ex.backtrace.nil?
|
121
|
+
end
|
66
122
|
end
|
123
|
+
###
|
67
124
|
|
68
125
|
##
|
69
126
|
# Configuration for Sidekiq server, use like:
|
70
127
|
#
|
71
128
|
# Sidekiq.configure_server do |config|
|
72
|
-
# config.redis = { :namespace => 'myapp', :size => 25, :url => 'redis://myhost:8877/0' }
|
73
129
|
# config.server_middleware do |chain|
|
74
130
|
# chain.add MyServerHook
|
75
131
|
# end
|
@@ -82,7 +138,7 @@ module Sidekiq
|
|
82
138
|
# Configuration for Sidekiq client, use like:
|
83
139
|
#
|
84
140
|
# Sidekiq.configure_client do |config|
|
85
|
-
# config.redis = { :
|
141
|
+
# config.redis = { size: 1, url: 'redis://myhost:8877/0' }
|
86
142
|
# end
|
87
143
|
def self.configure_client
|
88
144
|
yield self unless server?
|
@@ -98,7 +154,7 @@ module Sidekiq
|
|
98
154
|
retryable = true
|
99
155
|
begin
|
100
156
|
yield conn
|
101
|
-
rescue
|
157
|
+
rescue RedisConnection.adapter::BaseError => ex
|
102
158
|
# 2550 Failover can cause the server to become a replica, need
|
103
159
|
# to disconnect and reopen the socket to get back to the primary.
|
104
160
|
# 4495 Use the same logic if we have a "Not enough replicas" error from the primary
|
@@ -123,7 +179,7 @@ module Sidekiq
|
|
123
179
|
else
|
124
180
|
conn.info
|
125
181
|
end
|
126
|
-
rescue
|
182
|
+
rescue RedisConnection.adapter::CommandError => ex
|
127
183
|
# 2850 return fake version when INFO command has (probably) been renamed
|
128
184
|
raise unless /unknown command/.match?(ex.message)
|
129
185
|
FAKE_INFO
|
@@ -131,19 +187,19 @@ module Sidekiq
|
|
131
187
|
end
|
132
188
|
|
133
189
|
def self.redis_pool
|
134
|
-
@redis ||=
|
190
|
+
@redis ||= RedisConnection.create
|
135
191
|
end
|
136
192
|
|
137
193
|
def self.redis=(hash)
|
138
194
|
@redis = if hash.is_a?(ConnectionPool)
|
139
195
|
hash
|
140
196
|
else
|
141
|
-
|
197
|
+
RedisConnection.create(hash)
|
142
198
|
end
|
143
199
|
end
|
144
200
|
|
145
201
|
def self.client_middleware
|
146
|
-
@client_chain ||= Middleware::Chain.new
|
202
|
+
@client_chain ||= Middleware::Chain.new(self)
|
147
203
|
yield @client_chain if block_given?
|
148
204
|
@client_chain
|
149
205
|
end
|
@@ -155,16 +211,23 @@ module Sidekiq
|
|
155
211
|
end
|
156
212
|
|
157
213
|
def self.default_server_middleware
|
158
|
-
Middleware::Chain.new
|
214
|
+
Middleware::Chain.new(self)
|
215
|
+
end
|
216
|
+
|
217
|
+
def self.default_worker_options=(hash) # deprecated
|
218
|
+
@default_job_options = default_job_options.merge(hash.transform_keys(&:to_s))
|
159
219
|
end
|
160
220
|
|
161
|
-
def self.
|
162
|
-
|
163
|
-
@default_worker_options = default_worker_options.merge(hash.transform_keys(&:to_s))
|
221
|
+
def self.default_job_options=(hash)
|
222
|
+
@default_job_options = default_job_options.merge(hash.transform_keys(&:to_s))
|
164
223
|
end
|
165
224
|
|
166
|
-
def self.default_worker_options
|
167
|
-
|
225
|
+
def self.default_worker_options # deprecated
|
226
|
+
@default_job_options ||= {"retry" => true, "queue" => "default"}
|
227
|
+
end
|
228
|
+
|
229
|
+
def self.default_job_options
|
230
|
+
@default_job_options ||= {"retry" => true, "queue" => "default"}
|
168
231
|
end
|
169
232
|
|
170
233
|
##
|
@@ -177,7 +240,7 @@ module Sidekiq
|
|
177
240
|
# end
|
178
241
|
# end
|
179
242
|
def self.death_handlers
|
180
|
-
|
243
|
+
self[:death_handlers]
|
181
244
|
end
|
182
245
|
|
183
246
|
def self.load_json(string)
|
@@ -202,7 +265,7 @@ module Sidekiq
|
|
202
265
|
end
|
203
266
|
|
204
267
|
def self.logger
|
205
|
-
@logger ||= Sidekiq::Logger.new($stdout, level:
|
268
|
+
@logger ||= Sidekiq::Logger.new($stdout, level: :info)
|
206
269
|
end
|
207
270
|
|
208
271
|
def self.logger=(logger)
|
@@ -220,13 +283,17 @@ module Sidekiq
|
|
220
283
|
defined?(Sidekiq::Pro)
|
221
284
|
end
|
222
285
|
|
286
|
+
def self.ent?
|
287
|
+
defined?(Sidekiq::Enterprise)
|
288
|
+
end
|
289
|
+
|
223
290
|
# How frequently Redis should be checked by a random Sidekiq process for
|
224
291
|
# scheduled and retriable jobs. Each individual process will take turns by
|
225
292
|
# waiting some multiple of this value.
|
226
293
|
#
|
227
294
|
# See sidekiq/scheduled.rb for an in-depth explanation of this value
|
228
295
|
def self.average_scheduled_poll_interval=(interval)
|
229
|
-
|
296
|
+
self[:average_scheduled_poll_interval] = interval
|
230
297
|
end
|
231
298
|
|
232
299
|
# Register a proc to handle any error which occurs within the Sidekiq process.
|
@@ -237,7 +304,7 @@ module Sidekiq
|
|
237
304
|
#
|
238
305
|
# The default error handler logs errors to Sidekiq.logger.
|
239
306
|
def self.error_handlers
|
240
|
-
|
307
|
+
self[:error_handlers]
|
241
308
|
end
|
242
309
|
|
243
310
|
# Register a block to run at a point in the Sidekiq lifecycle.
|
@@ -250,20 +317,20 @@ module Sidekiq
|
|
250
317
|
# end
|
251
318
|
def self.on(event, &block)
|
252
319
|
raise ArgumentError, "Symbols only please: #{event}" unless event.is_a?(Symbol)
|
253
|
-
raise ArgumentError, "Invalid event name: #{event}" unless
|
254
|
-
|
320
|
+
raise ArgumentError, "Invalid event name: #{event}" unless self[:lifecycle_events].key?(event)
|
321
|
+
self[:lifecycle_events][event] << block
|
255
322
|
end
|
256
323
|
|
257
324
|
def self.strict_args!(mode = :raise)
|
258
|
-
|
325
|
+
self[:on_complex_arguments] = mode
|
259
326
|
end
|
260
327
|
|
261
|
-
# We are shutting down Sidekiq but what about
|
328
|
+
# We are shutting down Sidekiq but what about threads that
|
262
329
|
# are working on some long job? This error is
|
263
|
-
# raised in
|
330
|
+
# raised in jobs that have not finished within the hard
|
264
331
|
# timeout limit. This is needed to rollback db transactions,
|
265
332
|
# otherwise Ruby's Thread#kill will commit. See #377.
|
266
|
-
# DO NOT RESCUE THIS ERROR IN YOUR
|
333
|
+
# DO NOT RESCUE THIS ERROR IN YOUR JOBS
|
267
334
|
class Shutdown < Interrupt; end
|
268
335
|
end
|
269
336
|
|