sidekiq 6.2.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 +132 -1
- data/LICENSE +3 -3
- data/README.md +9 -4
- 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/.DS_Store +0 -0
- data/lib/sidekiq/api.rb +192 -135
- data/lib/sidekiq/cli.rb +59 -40
- data/lib/sidekiq/client.rb +46 -66
- data/lib/sidekiq/{util.rb → component.rb} +11 -42
- data/lib/sidekiq/delay.rb +3 -1
- data/lib/sidekiq/extensions/generic_proxy.rb +4 -2
- data/lib/sidekiq/fetch.rb +23 -20
- data/lib/sidekiq/job.rb +13 -0
- data/lib/sidekiq/job_logger.rb +16 -28
- data/lib/sidekiq/job_retry.rb +37 -38
- data/lib/sidekiq/job_util.rb +71 -0
- data/lib/sidekiq/launcher.rb +67 -65
- data/lib/sidekiq/logger.rb +8 -18
- data/lib/sidekiq/manager.rb +35 -34
- data/lib/sidekiq/middleware/chain.rb +27 -16
- data/lib/sidekiq/middleware/current_attributes.rb +61 -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 +38 -38
- data/lib/sidekiq/rails.rb +22 -4
- data/lib/sidekiq/redis_client_adapter.rb +154 -0
- data/lib/sidekiq/redis_connection.rb +85 -54
- data/lib/sidekiq/ring_buffer.rb +29 -0
- data/lib/sidekiq/scheduled.rb +60 -24
- 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 +1 -1
- data/lib/sidekiq/web/application.rb +9 -6
- data/lib/sidekiq/web/csrf_protection.rb +2 -2
- data/lib/sidekiq/web/helpers.rb +14 -26
- data/lib/sidekiq/web.rb +6 -5
- data/lib/sidekiq/worker.rb +136 -13
- data/lib/sidekiq.rb +105 -30
- data/sidekiq.gemspec +1 -1
- data/web/assets/javascripts/application.js +113 -60
- data/web/assets/javascripts/dashboard.js +51 -51
- data/web/assets/stylesheets/application-dark.css +28 -45
- data/web/assets/stylesheets/application-rtl.css +0 -4
- data/web/assets/stylesheets/application.css +24 -237
- data/web/locales/ar.yml +8 -2
- data/web/locales/en.yml +4 -1
- data/web/locales/es.yml +18 -2
- data/web/locales/fr.yml +7 -0
- data/web/locales/ja.yml +3 -0
- data/web/locales/lt.yml +1 -1
- data/web/locales/pt-br.yml +27 -9
- data/web/views/_footer.erb +1 -1
- data/web/views/_job_info.erb +1 -1
- data/web/views/_poll_link.erb +2 -5
- data/web/views/_summary.erb +7 -7
- data/web/views/busy.erb +8 -8
- data/web/views/dashboard.erb +22 -14
- data/web/views/dead.erb +1 -1
- data/web/views/layout.erb +1 -1
- data/web/views/morgue.erb +6 -6
- data/web/views/queue.erb +10 -10
- data/web/views/queues.erb +3 -3
- data/web/views/retries.erb +7 -7
- data/web/views/retry.erb +1 -1
- data/web/views/scheduled.erb +1 -1
- metadata +17 -10
- data/lib/generators/sidekiq/worker_generator.rb +0 -57
- data/lib/sidekiq/exception_handler.rb +0 -27
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,6 +27,7 @@ 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: {
|
@@ -38,11 +41,6 @@ module Sidekiq
|
|
38
41
|
reloader: proc { |&block| block.call }
|
39
42
|
}
|
40
43
|
|
41
|
-
DEFAULT_WORKER_OPTIONS = {
|
42
|
-
"retry" => true,
|
43
|
-
"queue" => "default"
|
44
|
-
}
|
45
|
-
|
46
44
|
FAKE_INFO = {
|
47
45
|
"redis_version" => "9.9.9",
|
48
46
|
"uptime_in_days" => "9999",
|
@@ -55,19 +53,79 @@ module Sidekiq
|
|
55
53
|
puts "Calm down, yo."
|
56
54
|
end
|
57
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
|
58
88
|
def self.options
|
59
|
-
|
89
|
+
logger.warn "`config.options[:key] = value` is deprecated, use `config[:key] = value`: #{caller(1..2)}"
|
90
|
+
@config
|
60
91
|
end
|
61
92
|
|
62
93
|
def self.options=(opts)
|
63
|
-
|
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
|
64
104
|
end
|
65
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
|
122
|
+
end
|
123
|
+
###
|
124
|
+
|
66
125
|
##
|
67
126
|
# Configuration for Sidekiq server, use like:
|
68
127
|
#
|
69
128
|
# Sidekiq.configure_server do |config|
|
70
|
-
# config.redis = { :namespace => 'myapp', :size => 25, :url => 'redis://myhost:8877/0' }
|
71
129
|
# config.server_middleware do |chain|
|
72
130
|
# chain.add MyServerHook
|
73
131
|
# end
|
@@ -80,7 +138,7 @@ module Sidekiq
|
|
80
138
|
# Configuration for Sidekiq client, use like:
|
81
139
|
#
|
82
140
|
# Sidekiq.configure_client do |config|
|
83
|
-
# config.redis = { :
|
141
|
+
# config.redis = { size: 1, url: 'redis://myhost:8877/0' }
|
84
142
|
# end
|
85
143
|
def self.configure_client
|
86
144
|
yield self unless server?
|
@@ -96,11 +154,13 @@ module Sidekiq
|
|
96
154
|
retryable = true
|
97
155
|
begin
|
98
156
|
yield conn
|
99
|
-
rescue
|
157
|
+
rescue RedisConnection.adapter::BaseError => ex
|
100
158
|
# 2550 Failover can cause the server to become a replica, need
|
101
159
|
# to disconnect and reopen the socket to get back to the primary.
|
102
160
|
# 4495 Use the same logic if we have a "Not enough replicas" error from the primary
|
103
|
-
|
161
|
+
# 4985 Use the same logic when a blocking command is force-unblocked
|
162
|
+
# The same retry logic is also used in client.rb
|
163
|
+
if retryable && ex.message =~ /READONLY|NOREPLICAS|UNBLOCKED/
|
104
164
|
conn.disconnect!
|
105
165
|
retryable = false
|
106
166
|
retry
|
@@ -119,7 +179,7 @@ module Sidekiq
|
|
119
179
|
else
|
120
180
|
conn.info
|
121
181
|
end
|
122
|
-
rescue
|
182
|
+
rescue RedisConnection.adapter::CommandError => ex
|
123
183
|
# 2850 return fake version when INFO command has (probably) been renamed
|
124
184
|
raise unless /unknown command/.match?(ex.message)
|
125
185
|
FAKE_INFO
|
@@ -127,19 +187,19 @@ module Sidekiq
|
|
127
187
|
end
|
128
188
|
|
129
189
|
def self.redis_pool
|
130
|
-
@redis ||=
|
190
|
+
@redis ||= RedisConnection.create
|
131
191
|
end
|
132
192
|
|
133
193
|
def self.redis=(hash)
|
134
194
|
@redis = if hash.is_a?(ConnectionPool)
|
135
195
|
hash
|
136
196
|
else
|
137
|
-
|
197
|
+
RedisConnection.create(hash)
|
138
198
|
end
|
139
199
|
end
|
140
200
|
|
141
201
|
def self.client_middleware
|
142
|
-
@client_chain ||= Middleware::Chain.new
|
202
|
+
@client_chain ||= Middleware::Chain.new(self)
|
143
203
|
yield @client_chain if block_given?
|
144
204
|
@client_chain
|
145
205
|
end
|
@@ -151,16 +211,23 @@ module Sidekiq
|
|
151
211
|
end
|
152
212
|
|
153
213
|
def self.default_server_middleware
|
154
|
-
Middleware::Chain.new
|
214
|
+
Middleware::Chain.new(self)
|
155
215
|
end
|
156
216
|
|
157
|
-
def self.default_worker_options=(hash)
|
158
|
-
|
159
|
-
@default_worker_options = default_worker_options.merge(hash.transform_keys(&:to_s))
|
217
|
+
def self.default_worker_options=(hash) # deprecated
|
218
|
+
@default_job_options = default_job_options.merge(hash.transform_keys(&:to_s))
|
160
219
|
end
|
161
220
|
|
162
|
-
def self.
|
163
|
-
|
221
|
+
def self.default_job_options=(hash)
|
222
|
+
@default_job_options = default_job_options.merge(hash.transform_keys(&:to_s))
|
223
|
+
end
|
224
|
+
|
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"}
|
164
231
|
end
|
165
232
|
|
166
233
|
##
|
@@ -173,7 +240,7 @@ module Sidekiq
|
|
173
240
|
# end
|
174
241
|
# end
|
175
242
|
def self.death_handlers
|
176
|
-
|
243
|
+
self[:death_handlers]
|
177
244
|
end
|
178
245
|
|
179
246
|
def self.load_json(string)
|
@@ -198,7 +265,7 @@ module Sidekiq
|
|
198
265
|
end
|
199
266
|
|
200
267
|
def self.logger
|
201
|
-
@logger ||= Sidekiq::Logger.new($stdout, level:
|
268
|
+
@logger ||= Sidekiq::Logger.new($stdout, level: :info)
|
202
269
|
end
|
203
270
|
|
204
271
|
def self.logger=(logger)
|
@@ -216,13 +283,17 @@ module Sidekiq
|
|
216
283
|
defined?(Sidekiq::Pro)
|
217
284
|
end
|
218
285
|
|
286
|
+
def self.ent?
|
287
|
+
defined?(Sidekiq::Enterprise)
|
288
|
+
end
|
289
|
+
|
219
290
|
# How frequently Redis should be checked by a random Sidekiq process for
|
220
291
|
# scheduled and retriable jobs. Each individual process will take turns by
|
221
292
|
# waiting some multiple of this value.
|
222
293
|
#
|
223
294
|
# See sidekiq/scheduled.rb for an in-depth explanation of this value
|
224
295
|
def self.average_scheduled_poll_interval=(interval)
|
225
|
-
|
296
|
+
self[:average_scheduled_poll_interval] = interval
|
226
297
|
end
|
227
298
|
|
228
299
|
# Register a proc to handle any error which occurs within the Sidekiq process.
|
@@ -233,7 +304,7 @@ module Sidekiq
|
|
233
304
|
#
|
234
305
|
# The default error handler logs errors to Sidekiq.logger.
|
235
306
|
def self.error_handlers
|
236
|
-
|
307
|
+
self[:error_handlers]
|
237
308
|
end
|
238
309
|
|
239
310
|
# Register a block to run at a point in the Sidekiq lifecycle.
|
@@ -246,16 +317,20 @@ module Sidekiq
|
|
246
317
|
# end
|
247
318
|
def self.on(event, &block)
|
248
319
|
raise ArgumentError, "Symbols only please: #{event}" unless event.is_a?(Symbol)
|
249
|
-
raise ArgumentError, "Invalid event name: #{event}" unless
|
250
|
-
|
320
|
+
raise ArgumentError, "Invalid event name: #{event}" unless self[:lifecycle_events].key?(event)
|
321
|
+
self[:lifecycle_events][event] << block
|
322
|
+
end
|
323
|
+
|
324
|
+
def self.strict_args!(mode = :raise)
|
325
|
+
self[:on_complex_arguments] = mode
|
251
326
|
end
|
252
327
|
|
253
|
-
# We are shutting down Sidekiq but what about
|
328
|
+
# We are shutting down Sidekiq but what about threads that
|
254
329
|
# are working on some long job? This error is
|
255
|
-
# raised in
|
330
|
+
# raised in jobs that have not finished within the hard
|
256
331
|
# timeout limit. This is needed to rollback db transactions,
|
257
332
|
# otherwise Ruby's Thread#kill will commit. See #377.
|
258
|
-
# DO NOT RESCUE THIS ERROR IN YOUR
|
333
|
+
# DO NOT RESCUE THIS ERROR IN YOUR JOBS
|
259
334
|
class Shutdown < Interrupt; end
|
260
335
|
end
|
261
336
|
|
data/sidekiq.gemspec
CHANGED
@@ -18,7 +18,7 @@ Gem::Specification.new do |gem|
|
|
18
18
|
"homepage_uri" => "https://sidekiq.org",
|
19
19
|
"bug_tracker_uri" => "https://github.com/mperham/sidekiq/issues",
|
20
20
|
"documentation_uri" => "https://github.com/mperham/sidekiq/wiki",
|
21
|
-
"changelog_uri" => "https://github.com/mperham/sidekiq/blob/
|
21
|
+
"changelog_uri" => "https://github.com/mperham/sidekiq/blob/main/Changes.md",
|
22
22
|
"source_code_uri" => "https://github.com/mperham/sidekiq"
|
23
23
|
}
|
24
24
|
|