sidekiq 6.3.1 → 7.0.0
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 +140 -4
- data/LICENSE.txt +9 -0
- data/README.md +19 -13
- data/bin/sidekiq +4 -9
- data/bin/sidekiqload +71 -76
- 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 +267 -186
- data/lib/sidekiq/capsule.rb +110 -0
- data/lib/sidekiq/cli.rb +82 -78
- data/lib/sidekiq/client.rb +73 -80
- data/lib/sidekiq/{util.rb → component.rb} +13 -42
- data/lib/sidekiq/config.rb +271 -0
- data/lib/sidekiq/deploy.rb +62 -0
- data/lib/sidekiq/embedded.rb +61 -0
- data/lib/sidekiq/fetch.rb +22 -21
- data/lib/sidekiq/job.rb +375 -10
- data/lib/sidekiq/job_logger.rb +16 -28
- data/lib/sidekiq/job_retry.rb +79 -56
- data/lib/sidekiq/job_util.rb +71 -0
- data/lib/sidekiq/launcher.rb +76 -82
- data/lib/sidekiq/logger.rb +9 -44
- data/lib/sidekiq/manager.rb +40 -41
- data/lib/sidekiq/metrics/query.rb +153 -0
- data/lib/sidekiq/metrics/shared.rb +95 -0
- data/lib/sidekiq/metrics/tracking.rb +134 -0
- data/lib/sidekiq/middleware/chain.rb +84 -42
- data/lib/sidekiq/middleware/current_attributes.rb +19 -13
- 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 +16 -8
- data/lib/sidekiq/processor.rb +56 -59
- data/lib/sidekiq/rails.rb +10 -9
- data/lib/sidekiq/redis_client_adapter.rb +118 -0
- data/lib/sidekiq/redis_connection.rb +13 -82
- data/lib/sidekiq/ring_buffer.rb +29 -0
- data/lib/sidekiq/scheduled.rb +75 -37
- data/lib/sidekiq/testing/inline.rb +4 -4
- data/lib/sidekiq/testing.rb +41 -68
- data/lib/sidekiq/transaction_aware_client.rb +44 -0
- data/lib/sidekiq/version.rb +2 -1
- data/lib/sidekiq/web/action.rb +3 -3
- data/lib/sidekiq/web/application.rb +27 -8
- data/lib/sidekiq/web/csrf_protection.rb +3 -3
- data/lib/sidekiq/web/helpers.rb +22 -20
- data/lib/sidekiq/web.rb +6 -17
- data/lib/sidekiq/worker_compatibility_alias.rb +13 -0
- data/lib/sidekiq.rb +85 -202
- data/sidekiq.gemspec +29 -5
- data/web/assets/javascripts/application.js +58 -26
- data/web/assets/javascripts/base-charts.js +106 -0
- 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-charts.js +166 -0
- data/web/assets/javascripts/dashboard.js +3 -240
- data/web/assets/javascripts/metrics.js +236 -0
- data/web/assets/stylesheets/application-dark.css +13 -17
- data/web/assets/stylesheets/application-rtl.css +2 -91
- data/web/assets/stylesheets/application.css +67 -300
- data/web/locales/ar.yml +70 -70
- data/web/locales/cs.yml +62 -62
- data/web/locales/da.yml +52 -52
- data/web/locales/de.yml +65 -65
- data/web/locales/el.yml +43 -24
- data/web/locales/en.yml +82 -69
- data/web/locales/es.yml +68 -68
- data/web/locales/fa.yml +65 -65
- data/web/locales/fr.yml +67 -67
- data/web/locales/he.yml +65 -64
- data/web/locales/hi.yml +59 -59
- data/web/locales/it.yml +53 -53
- data/web/locales/ja.yml +71 -68
- data/web/locales/ko.yml +52 -52
- data/web/locales/lt.yml +66 -66
- data/web/locales/nb.yml +61 -61
- data/web/locales/nl.yml +52 -52
- data/web/locales/pl.yml +45 -45
- data/web/locales/pt-br.yml +63 -55
- data/web/locales/pt.yml +51 -51
- data/web/locales/ru.yml +67 -66
- data/web/locales/sv.yml +53 -53
- data/web/locales/ta.yml +60 -60
- data/web/locales/uk.yml +62 -61
- data/web/locales/ur.yml +64 -64
- data/web/locales/vi.yml +67 -67
- data/web/locales/zh-cn.yml +37 -11
- data/web/locales/zh-tw.yml +42 -8
- data/web/views/_footer.erb +5 -2
- data/web/views/_nav.erb +1 -1
- data/web/views/_summary.erb +1 -1
- data/web/views/busy.erb +9 -4
- data/web/views/dashboard.erb +36 -4
- data/web/views/metrics.erb +80 -0
- data/web/views/metrics_for_job.erb +69 -0
- data/web/views/queue.erb +5 -1
- metadata +75 -27
- data/LICENSE +0 -9
- data/lib/generators/sidekiq/worker_generator.rb +0 -57
- data/lib/sidekiq/delay.rb +0 -41
- data/lib/sidekiq/exception_handler.rb +0 -27
- data/lib/sidekiq/extensions/action_mailer.rb +0 -48
- data/lib/sidekiq/extensions/active_record.rb +0 -43
- data/lib/sidekiq/extensions/class_methods.rb +0 -43
- data/lib/sidekiq/extensions/generic_proxy.rb +0 -33
- data/lib/sidekiq/worker.rb +0 -311
data/lib/sidekiq/testing.rb
CHANGED
@@ -51,19 +51,10 @@ module Sidekiq
|
|
51
51
|
end
|
52
52
|
|
53
53
|
def server_middleware
|
54
|
-
@server_chain ||= Middleware::Chain.new
|
54
|
+
@server_chain ||= Middleware::Chain.new(Sidekiq.default_configuration)
|
55
55
|
yield @server_chain if block_given?
|
56
56
|
@server_chain
|
57
57
|
end
|
58
|
-
|
59
|
-
def constantize(str)
|
60
|
-
names = str.split("::")
|
61
|
-
names.shift if names.empty? || names.first.empty?
|
62
|
-
|
63
|
-
names.inject(Object) do |constant, name|
|
64
|
-
constant.const_defined?(name) ? constant.const_get(name) : constant.const_missing(name)
|
65
|
-
end
|
66
|
-
end
|
67
58
|
end
|
68
59
|
end
|
69
60
|
|
@@ -83,7 +74,7 @@ module Sidekiq
|
|
83
74
|
true
|
84
75
|
elsif Sidekiq::Testing.inline?
|
85
76
|
payloads.each do |job|
|
86
|
-
klass =
|
77
|
+
klass = Object.const_get(job["class"])
|
87
78
|
job["id"] ||= SecureRandom.hex(12)
|
88
79
|
job_hash = Sidekiq.load_json(Sidekiq.dump_json(job))
|
89
80
|
klass.process_job(job_hash)
|
@@ -101,20 +92,20 @@ module Sidekiq
|
|
101
92
|
##
|
102
93
|
# The Queues class is only for testing the fake queue implementation.
|
103
94
|
# There are 2 data structures involved in tandem. This is due to the
|
104
|
-
# Rspec syntax of change(
|
95
|
+
# Rspec syntax of change(HardJob.jobs, :size). It keeps a reference
|
105
96
|
# to the array. Because the array was dervied from a filter of the total
|
106
97
|
# jobs enqueued, it appeared as though the array didn't change.
|
107
98
|
#
|
108
99
|
# 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
|
-
#
|
100
|
+
# on the queue, and another with keys of the job type, so the array for
|
101
|
+
# HardJob.jobs is a straight reference to a real array.
|
111
102
|
#
|
112
103
|
# Queue-based hash:
|
113
104
|
#
|
114
105
|
# {
|
115
106
|
# "default"=>[
|
116
107
|
# {
|
117
|
-
# "class"=>"TestTesting::
|
108
|
+
# "class"=>"TestTesting::HardJob",
|
118
109
|
# "args"=>[1, 2],
|
119
110
|
# "retry"=>true,
|
120
111
|
# "queue"=>"default",
|
@@ -124,12 +115,12 @@ module Sidekiq
|
|
124
115
|
# ]
|
125
116
|
# }
|
126
117
|
#
|
127
|
-
#
|
118
|
+
# Job-based hash:
|
128
119
|
#
|
129
120
|
# {
|
130
|
-
# "TestTesting::
|
121
|
+
# "TestTesting::HardJob"=>[
|
131
122
|
# {
|
132
|
-
# "class"=>"TestTesting::
|
123
|
+
# "class"=>"TestTesting::HardJob",
|
133
124
|
# "args"=>[1, 2],
|
134
125
|
# "retry"=>true,
|
135
126
|
# "queue"=>"default",
|
@@ -144,14 +135,14 @@ module Sidekiq
|
|
144
135
|
# require 'sidekiq/testing'
|
145
136
|
#
|
146
137
|
# assert_equal 0, Sidekiq::Queues["default"].size
|
147
|
-
#
|
138
|
+
# HardJob.perform_async(:something)
|
148
139
|
# assert_equal 1, Sidekiq::Queues["default"].size
|
149
140
|
# assert_equal :something, Sidekiq::Queues["default"].first['args'][0]
|
150
141
|
#
|
151
|
-
# You can also clear all
|
142
|
+
# You can also clear all jobs:
|
152
143
|
#
|
153
144
|
# assert_equal 0, Sidekiq::Queues["default"].size
|
154
|
-
#
|
145
|
+
# HardJob.perform_async(:something)
|
155
146
|
# Sidekiq::Queues.clear_all
|
156
147
|
# assert_equal 0, Sidekiq::Queues["default"].size
|
157
148
|
#
|
@@ -170,35 +161,36 @@ module Sidekiq
|
|
170
161
|
|
171
162
|
def push(queue, klass, job)
|
172
163
|
jobs_by_queue[queue] << job
|
173
|
-
|
164
|
+
jobs_by_class[klass] << job
|
174
165
|
end
|
175
166
|
|
176
167
|
def jobs_by_queue
|
177
168
|
@jobs_by_queue ||= Hash.new { |hash, key| hash[key] = [] }
|
178
169
|
end
|
179
170
|
|
180
|
-
def
|
181
|
-
@
|
171
|
+
def jobs_by_class
|
172
|
+
@jobs_by_class ||= Hash.new { |hash, key| hash[key] = [] }
|
182
173
|
end
|
174
|
+
alias_method :jobs_by_worker, :jobs_by_class
|
183
175
|
|
184
176
|
def delete_for(jid, queue, klass)
|
185
177
|
jobs_by_queue[queue.to_s].delete_if { |job| job["jid"] == jid }
|
186
|
-
|
178
|
+
jobs_by_class[klass].delete_if { |job| job["jid"] == jid }
|
187
179
|
end
|
188
180
|
|
189
181
|
def clear_for(queue, klass)
|
190
|
-
jobs_by_queue[queue].clear
|
191
|
-
|
182
|
+
jobs_by_queue[queue.to_s].clear
|
183
|
+
jobs_by_class[klass].clear
|
192
184
|
end
|
193
185
|
|
194
186
|
def clear_all
|
195
187
|
jobs_by_queue.clear
|
196
|
-
|
188
|
+
jobs_by_class.clear
|
197
189
|
end
|
198
190
|
end
|
199
191
|
end
|
200
192
|
|
201
|
-
module
|
193
|
+
module Job
|
202
194
|
##
|
203
195
|
# The Sidekiq testing infrastructure overrides perform_async
|
204
196
|
# so that it does not actually touch the network. Instead it
|
@@ -212,43 +204,27 @@ module Sidekiq
|
|
212
204
|
#
|
213
205
|
# require 'sidekiq/testing'
|
214
206
|
#
|
215
|
-
# assert_equal 0,
|
216
|
-
#
|
217
|
-
# assert_equal 1,
|
218
|
-
# assert_equal :something,
|
219
|
-
#
|
220
|
-
# assert_equal 0, Sidekiq::Extensions::DelayedMailer.jobs.size
|
221
|
-
# MyMailer.delay.send_welcome_email('foo@example.com')
|
222
|
-
# assert_equal 1, Sidekiq::Extensions::DelayedMailer.jobs.size
|
207
|
+
# assert_equal 0, HardJob.jobs.size
|
208
|
+
# HardJob.perform_async(:something)
|
209
|
+
# assert_equal 1, HardJob.jobs.size
|
210
|
+
# assert_equal :something, HardJob.jobs[0]['args'][0]
|
223
211
|
#
|
224
|
-
# You can also clear and drain all
|
212
|
+
# You can also clear and drain all job types:
|
225
213
|
#
|
226
|
-
#
|
227
|
-
# assert_equal 0, Sidekiq::Extensions::DelayedModel.jobs.size
|
228
|
-
#
|
229
|
-
# MyMailer.delay.send_welcome_email('foo@example.com')
|
230
|
-
# MyModel.delay.do_something_hard
|
231
|
-
#
|
232
|
-
# assert_equal 1, Sidekiq::Extensions::DelayedMailer.jobs.size
|
233
|
-
# assert_equal 1, Sidekiq::Extensions::DelayedModel.jobs.size
|
234
|
-
#
|
235
|
-
# Sidekiq::Worker.clear_all # or .drain_all
|
236
|
-
#
|
237
|
-
# assert_equal 0, Sidekiq::Extensions::DelayedMailer.jobs.size
|
238
|
-
# assert_equal 0, Sidekiq::Extensions::DelayedModel.jobs.size
|
214
|
+
# Sidekiq::Job.clear_all # or .drain_all
|
239
215
|
#
|
240
216
|
# This can be useful to make sure jobs don't linger between tests:
|
241
217
|
#
|
242
218
|
# RSpec.configure do |config|
|
243
219
|
# config.before(:each) do
|
244
|
-
# Sidekiq::
|
220
|
+
# Sidekiq::Job.clear_all
|
245
221
|
# end
|
246
222
|
# end
|
247
223
|
#
|
248
224
|
# or for acceptance testing, i.e. with cucumber:
|
249
225
|
#
|
250
226
|
# AfterStep do
|
251
|
-
# Sidekiq::
|
227
|
+
# Sidekiq::Job.drain_all
|
252
228
|
# end
|
253
229
|
#
|
254
230
|
# When I sign up as "foo@example.com"
|
@@ -262,7 +238,7 @@ module Sidekiq
|
|
262
238
|
|
263
239
|
# Jobs queued for this worker
|
264
240
|
def jobs
|
265
|
-
Queues.
|
241
|
+
Queues.jobs_by_class[to_s]
|
266
242
|
end
|
267
243
|
|
268
244
|
# Clear all jobs for this worker
|
@@ -288,11 +264,11 @@ module Sidekiq
|
|
288
264
|
end
|
289
265
|
|
290
266
|
def process_job(job)
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
Sidekiq::Testing.server_middleware.invoke(
|
295
|
-
execute_job(
|
267
|
+
inst = new
|
268
|
+
inst.jid = job["jid"]
|
269
|
+
inst.bid = job["bid"] if inst.respond_to?(:bid=)
|
270
|
+
Sidekiq::Testing.server_middleware.invoke(inst, job, job["queue"]) do
|
271
|
+
execute_job(inst, job["args"])
|
296
272
|
end
|
297
273
|
end
|
298
274
|
|
@@ -306,18 +282,18 @@ module Sidekiq
|
|
306
282
|
Queues.jobs_by_queue.values.flatten
|
307
283
|
end
|
308
284
|
|
309
|
-
# Clear all queued jobs
|
285
|
+
# Clear all queued jobs
|
310
286
|
def clear_all
|
311
287
|
Queues.clear_all
|
312
288
|
end
|
313
289
|
|
314
|
-
# Drain all queued jobs
|
290
|
+
# Drain (execute) all queued jobs
|
315
291
|
def drain_all
|
316
292
|
while jobs.any?
|
317
|
-
|
293
|
+
job_classes = jobs.map { |job| job["class"] }.uniq
|
318
294
|
|
319
|
-
|
320
|
-
|
295
|
+
job_classes.each do |job_class|
|
296
|
+
Object.const_get(job_class).drain
|
321
297
|
end
|
322
298
|
end
|
323
299
|
end
|
@@ -328,13 +304,10 @@ module Sidekiq
|
|
328
304
|
def jobs_for(klass)
|
329
305
|
jobs.select do |job|
|
330
306
|
marshalled = job["args"][0]
|
331
|
-
marshalled.index(klass.to_s) && YAML.
|
307
|
+
marshalled.index(klass.to_s) && YAML.safe_load(marshalled)[0] == klass
|
332
308
|
end
|
333
309
|
end
|
334
310
|
end
|
335
|
-
|
336
|
-
Sidekiq::Extensions::DelayedMailer.extend(TestingExtensions) if defined?(Sidekiq::Extensions::DelayedMailer)
|
337
|
-
Sidekiq::Extensions::DelayedModel.extend(TestingExtensions) if defined?(Sidekiq::Extensions::DelayedModel)
|
338
311
|
end
|
339
312
|
|
340
313
|
if defined?(::Rails) && Rails.respond_to?(:env) && !Rails.env.test? && !$TESTING
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "securerandom"
|
4
|
+
require "sidekiq/client"
|
5
|
+
|
6
|
+
module Sidekiq
|
7
|
+
class TransactionAwareClient
|
8
|
+
def initialize(pool: nil, config: nil)
|
9
|
+
@redis_client = Client.new(pool: pool, config: config)
|
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
|
+
raise %q(You need to add `gem "after_commit_everywhere"` to your Gemfile to use Sidekiq's transactional client)
|
38
|
+
end
|
39
|
+
|
40
|
+
Sidekiq.default_job_options["client_class"] = Sidekiq::TransactionAwareClient
|
41
|
+
Sidekiq::JobUtil::TRANSIENT_ATTRIBUTES << "client_class"
|
42
|
+
true
|
43
|
+
end
|
44
|
+
end
|
data/lib/sidekiq/version.rb
CHANGED
data/lib/sidekiq/web/action.rb
CHANGED
@@ -15,11 +15,11 @@ module Sidekiq
|
|
15
15
|
end
|
16
16
|
|
17
17
|
def halt(res)
|
18
|
-
throw :halt, [res, {"
|
18
|
+
throw :halt, [res, {"content-type" => "text/plain"}, [res.to_s]]
|
19
19
|
end
|
20
20
|
|
21
21
|
def redirect(location)
|
22
|
-
throw :halt, [302, {"
|
22
|
+
throw :halt, [302, {"location" => "#{request.base_url}#{location}"}, []]
|
23
23
|
end
|
24
24
|
|
25
25
|
def params
|
@@ -68,7 +68,7 @@ module Sidekiq
|
|
68
68
|
end
|
69
69
|
|
70
70
|
def json(payload)
|
71
|
-
[200, {"
|
71
|
+
[200, {"content-type" => "application/json", "cache-control" => "private, no-store"}, [Sidekiq.dump_json(payload)]]
|
72
72
|
end
|
73
73
|
|
74
74
|
def initialize(env, block)
|
@@ -50,14 +50,33 @@ module Sidekiq
|
|
50
50
|
|
51
51
|
get "/" do
|
52
52
|
@redis_info = redis_info.select { |k, v| REDIS_KEYS.include? k }
|
53
|
-
|
53
|
+
days = (params["days"] || 30).to_i
|
54
|
+
return halt(401) if days < 1 || days > 180
|
55
|
+
|
56
|
+
stats_history = Sidekiq::Stats::History.new(days)
|
54
57
|
@processed_history = stats_history.processed
|
55
58
|
@failed_history = stats_history.failed
|
56
59
|
|
57
60
|
erb(:dashboard)
|
58
61
|
end
|
59
62
|
|
63
|
+
get "/metrics" do
|
64
|
+
q = Sidekiq::Metrics::Query.new
|
65
|
+
@query_result = q.top_jobs
|
66
|
+
erb(:metrics)
|
67
|
+
end
|
68
|
+
|
69
|
+
get "/metrics/:name" do
|
70
|
+
@name = route_params[:name]
|
71
|
+
q = Sidekiq::Metrics::Query.new
|
72
|
+
@query_result = q.for_job(@name)
|
73
|
+
erb(:metrics_for_job)
|
74
|
+
end
|
75
|
+
|
60
76
|
get "/busy" do
|
77
|
+
@count = (params["count"] || 100).to_i
|
78
|
+
(@current_page, @total_size, @workset) = page_items(workset, params["page"], @count)
|
79
|
+
|
61
80
|
erb(:busy)
|
62
81
|
end
|
63
82
|
|
@@ -291,15 +310,15 @@ module Sidekiq
|
|
291
310
|
end
|
292
311
|
|
293
312
|
get "/stats/queues" do
|
294
|
-
json Sidekiq::Stats
|
313
|
+
json Sidekiq::Stats.new.queues
|
295
314
|
end
|
296
315
|
|
297
316
|
def call(env)
|
298
317
|
action = self.class.match(env)
|
299
|
-
return [404, {"
|
318
|
+
return [404, {"content-type" => "text/plain", "x-cascade" => "pass"}, ["Not Found"]] unless action
|
300
319
|
|
301
320
|
app = @klass
|
302
|
-
resp = catch(:halt) do
|
321
|
+
resp = catch(:halt) do
|
303
322
|
self.class.run_befores(app, action)
|
304
323
|
action.instance_exec env, &action.block
|
305
324
|
ensure
|
@@ -313,10 +332,10 @@ module Sidekiq
|
|
313
332
|
else
|
314
333
|
# rendered content goes here
|
315
334
|
headers = {
|
316
|
-
"
|
317
|
-
"
|
318
|
-
"
|
319
|
-
"
|
335
|
+
"content-type" => "text/html",
|
336
|
+
"cache-control" => "private, no-store",
|
337
|
+
"content-language" => action.locale,
|
338
|
+
"content-security-policy" => CSP_HEADER
|
320
339
|
}
|
321
340
|
# we'll let Rack calculate Content-Length for us.
|
322
341
|
[200, headers, [resp]]
|
@@ -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+.
|
@@ -152,7 +152,7 @@ module Sidekiq
|
|
152
152
|
# value and decrypt it
|
153
153
|
token_length = masked_token.length / 2
|
154
154
|
one_time_pad = masked_token[0...token_length]
|
155
|
-
encrypted_token = masked_token[token_length
|
155
|
+
encrypted_token = masked_token[token_length..]
|
156
156
|
xor_byte_strings(one_time_pad, encrypted_token)
|
157
157
|
end
|
158
158
|
|
@@ -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
@@ -15,7 +15,7 @@ module Sidekiq
|
|
15
15
|
# so extensions can be localized
|
16
16
|
@strings[lang] ||= settings.locales.each_with_object({}) do |path, global|
|
17
17
|
find_locale_files(lang).each do |file|
|
18
|
-
strs = YAML.
|
18
|
+
strs = YAML.safe_load(File.open(file))
|
19
19
|
global.merge!(strs[lang])
|
20
20
|
end
|
21
21
|
end
|
@@ -140,30 +140,39 @@ 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
|
148
148
|
@processes ||= Sidekiq::ProcessSet.new
|
149
149
|
end
|
150
150
|
|
151
|
+
# Sorts processes by hostname following the natural sort order
|
152
|
+
def sorted_processes
|
153
|
+
@sorted_processes ||= begin
|
154
|
+
return processes unless processes.all? { |p| p["hostname"] }
|
155
|
+
|
156
|
+
processes.to_a.sort_by do |process|
|
157
|
+
# Kudos to `shurikk` on StackOverflow
|
158
|
+
# https://stackoverflow.com/a/15170063/575547
|
159
|
+
process["hostname"].split(/(\d+)/).map { |a| /\d+/.match?(a) ? a.to_i : a }
|
160
|
+
end
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
151
164
|
def stats
|
152
165
|
@stats ||= Sidekiq::Stats.new
|
153
166
|
end
|
154
167
|
|
155
|
-
def
|
168
|
+
def redis_url
|
156
169
|
Sidekiq.redis do |conn|
|
157
|
-
conn.
|
170
|
+
conn._config.server_url
|
158
171
|
end
|
159
172
|
end
|
160
173
|
|
161
|
-
def namespace
|
162
|
-
@ns ||= Sidekiq.redis { |conn| conn.respond_to?(:namespace) ? conn.namespace : nil }
|
163
|
-
end
|
164
|
-
|
165
174
|
def redis_info
|
166
|
-
Sidekiq.redis_info
|
175
|
+
Sidekiq.default_configuration.redis_info
|
167
176
|
end
|
168
177
|
|
169
178
|
def root_path
|
@@ -175,7 +184,7 @@ module Sidekiq
|
|
175
184
|
end
|
176
185
|
|
177
186
|
def current_status
|
178
|
-
|
187
|
+
workset.size == 0 ? "idle" : "active"
|
179
188
|
end
|
180
189
|
|
181
190
|
def relative_time(time)
|
@@ -242,7 +251,7 @@ module Sidekiq
|
|
242
251
|
queue class args retry_count retried_at failed_at
|
243
252
|
jid error_message error_class backtrace
|
244
253
|
error_backtrace enqueued_at retry wrapped
|
245
|
-
created_at tags
|
254
|
+
created_at tags display_class
|
246
255
|
])
|
247
256
|
|
248
257
|
def retry_extra_items(retry_job)
|
@@ -301,7 +310,7 @@ module Sidekiq
|
|
301
310
|
end
|
302
311
|
|
303
312
|
def environment_title_prefix
|
304
|
-
environment = Sidekiq.
|
313
|
+
environment = Sidekiq.default_configuration[:environment] || ENV["APP_ENV"] || ENV["RAILS_ENV"] || ENV["RACK_ENV"] || "development"
|
305
314
|
|
306
315
|
"[#{environment.upcase}] " unless environment == "production"
|
307
316
|
end
|
@@ -314,13 +323,6 @@ module Sidekiq
|
|
314
323
|
Time.now.utc.strftime("%H:%M:%S UTC")
|
315
324
|
end
|
316
325
|
|
317
|
-
def redis_connection_and_namespace
|
318
|
-
@redis_connection_and_namespace ||= begin
|
319
|
-
namespace_suffix = namespace.nil? ? "" : "##{namespace}"
|
320
|
-
"#{redis_connection}#{namespace_suffix}"
|
321
|
-
end
|
322
|
-
end
|
323
|
-
|
324
326
|
def retry_or_delete_or_kill(job, params)
|
325
327
|
if params["retry"]
|
326
328
|
job.retry
|
data/lib/sidekiq/web.rb
CHANGED
@@ -30,7 +30,8 @@ module Sidekiq
|
|
30
30
|
"Queues" => "queues",
|
31
31
|
"Retries" => "retries",
|
32
32
|
"Scheduled" => "scheduled",
|
33
|
-
"Dead" => "morgue"
|
33
|
+
"Dead" => "morgue",
|
34
|
+
"Metrics" => "metrics"
|
34
35
|
}
|
35
36
|
|
36
37
|
class << self
|
@@ -75,14 +76,6 @@ module Sidekiq
|
|
75
76
|
send(:"#{attribute}=", value)
|
76
77
|
end
|
77
78
|
|
78
|
-
def sessions=(val)
|
79
|
-
puts "WARNING: Sidekiq::Web.sessions= is no longer relevant and will be removed in Sidekiq 7.0. #{caller(1..1).first}"
|
80
|
-
end
|
81
|
-
|
82
|
-
def session_secret=(val)
|
83
|
-
puts "WARNING: Sidekiq::Web.session_secret= is no longer relevant and will be removed in Sidekiq 7.0. #{caller(1..1).first}"
|
84
|
-
end
|
85
|
-
|
86
79
|
attr_accessor :app_url, :redis_pool
|
87
80
|
attr_writer :locales, :views
|
88
81
|
end
|
@@ -129,10 +122,6 @@ module Sidekiq
|
|
129
122
|
send(:"#{attribute}=", value)
|
130
123
|
end
|
131
124
|
|
132
|
-
def sessions=(val)
|
133
|
-
puts "Sidekiq::Web#sessions= is no longer relevant and will be removed in Sidekiq 7.0. #{caller[2..2].first}"
|
134
|
-
end
|
135
|
-
|
136
125
|
def self.register(extension)
|
137
126
|
extension.registered(WebApplication)
|
138
127
|
end
|
@@ -144,13 +133,13 @@ module Sidekiq
|
|
144
133
|
m = middlewares
|
145
134
|
|
146
135
|
rules = []
|
147
|
-
rules = [[:all, {"
|
136
|
+
rules = [[:all, {"cache-control" => "public, max-age=86400"}]] unless ENV["SIDEKIQ_WEB_TESTING"]
|
148
137
|
|
149
138
|
::Rack::Builder.new do
|
150
139
|
use Rack::Static, urls: ["/stylesheets", "/images", "/javascripts"],
|
151
|
-
|
152
|
-
|
153
|
-
|
140
|
+
root: ASSETS,
|
141
|
+
cascade: true,
|
142
|
+
header_rules: rules
|
154
143
|
m.each { |middleware, block| use(*middleware, &block) }
|
155
144
|
use Sidekiq::Web::CsrfProtection unless $TESTING
|
156
145
|
run WebApplication.new(klass)
|
@@ -0,0 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Sidekiq
|
4
|
+
# Sidekiq::Job is a new alias for Sidekiq::Worker as of Sidekiq 6.3.0.
|
5
|
+
# Use `include Sidekiq::Job` rather than `include Sidekiq::Worker`.
|
6
|
+
#
|
7
|
+
# The term "worker" is too generic and overly confusing, used in several
|
8
|
+
# different contexts meaning different things. Many people call a Sidekiq
|
9
|
+
# process a "worker". Some people call the thread that executes jobs a
|
10
|
+
# "worker". This change brings Sidekiq closer to ActiveJob where your job
|
11
|
+
# classes extend ApplicationJob.
|
12
|
+
Worker = Job
|
13
|
+
end
|