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.

Files changed (110) hide show
  1. checksums.yaml +4 -4
  2. data/Changes.md +140 -4
  3. data/LICENSE.txt +9 -0
  4. data/README.md +19 -13
  5. data/bin/sidekiq +4 -9
  6. data/bin/sidekiqload +71 -76
  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 +267 -186
  13. data/lib/sidekiq/capsule.rb +110 -0
  14. data/lib/sidekiq/cli.rb +82 -78
  15. data/lib/sidekiq/client.rb +73 -80
  16. data/lib/sidekiq/{util.rb → component.rb} +13 -42
  17. data/lib/sidekiq/config.rb +271 -0
  18. data/lib/sidekiq/deploy.rb +62 -0
  19. data/lib/sidekiq/embedded.rb +61 -0
  20. data/lib/sidekiq/fetch.rb +22 -21
  21. data/lib/sidekiq/job.rb +375 -10
  22. data/lib/sidekiq/job_logger.rb +16 -28
  23. data/lib/sidekiq/job_retry.rb +79 -56
  24. data/lib/sidekiq/job_util.rb +71 -0
  25. data/lib/sidekiq/launcher.rb +76 -82
  26. data/lib/sidekiq/logger.rb +9 -44
  27. data/lib/sidekiq/manager.rb +40 -41
  28. data/lib/sidekiq/metrics/query.rb +153 -0
  29. data/lib/sidekiq/metrics/shared.rb +95 -0
  30. data/lib/sidekiq/metrics/tracking.rb +134 -0
  31. data/lib/sidekiq/middleware/chain.rb +84 -42
  32. data/lib/sidekiq/middleware/current_attributes.rb +19 -13
  33. data/lib/sidekiq/middleware/i18n.rb +6 -4
  34. data/lib/sidekiq/middleware/modules.rb +21 -0
  35. data/lib/sidekiq/monitor.rb +1 -1
  36. data/lib/sidekiq/paginator.rb +16 -8
  37. data/lib/sidekiq/processor.rb +56 -59
  38. data/lib/sidekiq/rails.rb +10 -9
  39. data/lib/sidekiq/redis_client_adapter.rb +118 -0
  40. data/lib/sidekiq/redis_connection.rb +13 -82
  41. data/lib/sidekiq/ring_buffer.rb +29 -0
  42. data/lib/sidekiq/scheduled.rb +75 -37
  43. data/lib/sidekiq/testing/inline.rb +4 -4
  44. data/lib/sidekiq/testing.rb +41 -68
  45. data/lib/sidekiq/transaction_aware_client.rb +44 -0
  46. data/lib/sidekiq/version.rb +2 -1
  47. data/lib/sidekiq/web/action.rb +3 -3
  48. data/lib/sidekiq/web/application.rb +27 -8
  49. data/lib/sidekiq/web/csrf_protection.rb +3 -3
  50. data/lib/sidekiq/web/helpers.rb +22 -20
  51. data/lib/sidekiq/web.rb +6 -17
  52. data/lib/sidekiq/worker_compatibility_alias.rb +13 -0
  53. data/lib/sidekiq.rb +85 -202
  54. data/sidekiq.gemspec +29 -5
  55. data/web/assets/javascripts/application.js +58 -26
  56. data/web/assets/javascripts/base-charts.js +106 -0
  57. data/web/assets/javascripts/chart.min.js +13 -0
  58. data/web/assets/javascripts/chartjs-plugin-annotation.min.js +7 -0
  59. data/web/assets/javascripts/dashboard-charts.js +166 -0
  60. data/web/assets/javascripts/dashboard.js +3 -240
  61. data/web/assets/javascripts/metrics.js +236 -0
  62. data/web/assets/stylesheets/application-dark.css +13 -17
  63. data/web/assets/stylesheets/application-rtl.css +2 -91
  64. data/web/assets/stylesheets/application.css +67 -300
  65. data/web/locales/ar.yml +70 -70
  66. data/web/locales/cs.yml +62 -62
  67. data/web/locales/da.yml +52 -52
  68. data/web/locales/de.yml +65 -65
  69. data/web/locales/el.yml +43 -24
  70. data/web/locales/en.yml +82 -69
  71. data/web/locales/es.yml +68 -68
  72. data/web/locales/fa.yml +65 -65
  73. data/web/locales/fr.yml +67 -67
  74. data/web/locales/he.yml +65 -64
  75. data/web/locales/hi.yml +59 -59
  76. data/web/locales/it.yml +53 -53
  77. data/web/locales/ja.yml +71 -68
  78. data/web/locales/ko.yml +52 -52
  79. data/web/locales/lt.yml +66 -66
  80. data/web/locales/nb.yml +61 -61
  81. data/web/locales/nl.yml +52 -52
  82. data/web/locales/pl.yml +45 -45
  83. data/web/locales/pt-br.yml +63 -55
  84. data/web/locales/pt.yml +51 -51
  85. data/web/locales/ru.yml +67 -66
  86. data/web/locales/sv.yml +53 -53
  87. data/web/locales/ta.yml +60 -60
  88. data/web/locales/uk.yml +62 -61
  89. data/web/locales/ur.yml +64 -64
  90. data/web/locales/vi.yml +67 -67
  91. data/web/locales/zh-cn.yml +37 -11
  92. data/web/locales/zh-tw.yml +42 -8
  93. data/web/views/_footer.erb +5 -2
  94. data/web/views/_nav.erb +1 -1
  95. data/web/views/_summary.erb +1 -1
  96. data/web/views/busy.erb +9 -4
  97. data/web/views/dashboard.erb +36 -4
  98. data/web/views/metrics.erb +80 -0
  99. data/web/views/metrics_for_job.erb +69 -0
  100. data/web/views/queue.erb +5 -1
  101. metadata +75 -27
  102. data/LICENSE +0 -9
  103. data/lib/generators/sidekiq/worker_generator.rb +0 -57
  104. data/lib/sidekiq/delay.rb +0 -41
  105. data/lib/sidekiq/exception_handler.rb +0 -27
  106. data/lib/sidekiq/extensions/action_mailer.rb +0 -48
  107. data/lib/sidekiq/extensions/active_record.rb +0 -43
  108. data/lib/sidekiq/extensions/class_methods.rb +0 -43
  109. data/lib/sidekiq/extensions/generic_proxy.rb +0 -33
  110. data/lib/sidekiq/worker.rb +0 -311
@@ -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 = Sidekiq::Testing.constantize(job["class"])
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(QueueWorker.jobs, :size). It keeps a reference
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 worker names, so the array for
110
- # QueueWorker.jobs is a straight reference to a real array.
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::QueueWorker",
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
- # Worker-based hash:
118
+ # Job-based hash:
128
119
  #
129
120
  # {
130
- # "TestTesting::QueueWorker"=>[
121
+ # "TestTesting::HardJob"=>[
131
122
  # {
132
- # "class"=>"TestTesting::QueueWorker",
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
- # HardWorker.perform_async(:something)
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 workers' jobs:
142
+ # You can also clear all jobs:
152
143
  #
153
144
  # assert_equal 0, Sidekiq::Queues["default"].size
154
- # HardWorker.perform_async(:something)
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
- jobs_by_worker[klass] << job
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 jobs_by_worker
181
- @jobs_by_worker ||= Hash.new { |hash, key| hash[key] = [] }
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
- jobs_by_worker[klass].delete_if { |job| job["jid"] == jid }
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
- jobs_by_worker[klass].clear
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
- jobs_by_worker.clear
188
+ jobs_by_class.clear
197
189
  end
198
190
  end
199
191
  end
200
192
 
201
- module Worker
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, HardWorker.jobs.size
216
- # HardWorker.perform_async(:something)
217
- # assert_equal 1, HardWorker.jobs.size
218
- # assert_equal :something, HardWorker.jobs[0]['args'][0]
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 workers' jobs:
212
+ # You can also clear and drain all job types:
225
213
  #
226
- # assert_equal 0, Sidekiq::Extensions::DelayedMailer.jobs.size
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::Worker.clear_all
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::Worker.drain_all
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.jobs_by_worker[to_s]
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
- worker = new
292
- worker.jid = job["jid"]
293
- worker.bid = job["bid"] if worker.respond_to?(:bid=)
294
- Sidekiq::Testing.server_middleware.invoke(worker, job, job["queue"]) do
295
- execute_job(worker, job["args"])
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 across all workers
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 across all workers
290
+ # Drain (execute) all queued jobs
315
291
  def drain_all
316
292
  while jobs.any?
317
- worker_classes = jobs.map { |job| job["class"] }.uniq
293
+ job_classes = jobs.map { |job| job["class"] }.uniq
318
294
 
319
- worker_classes.each do |worker_class|
320
- Sidekiq::Testing.constantize(worker_class).drain
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.load(marshalled)[0] == klass
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
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Sidekiq
4
- VERSION = "6.3.1"
4
+ VERSION = "7.0.0"
5
+ MAJOR = 7
5
6
  end
@@ -15,11 +15,11 @@ module Sidekiq
15
15
  end
16
16
 
17
17
  def halt(res)
18
- throw :halt, [res, {"Content-Type" => "text/plain"}, [res.to_s]]
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, {"Location" => "#{request.base_url}#{location}"}, []]
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, {"Content-Type" => "application/json", "Cache-Control" => "private, no-store"}, [Sidekiq.dump_json(payload)]]
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
- stats_history = Sidekiq::Stats::History.new((params["days"] || 30).to_i)
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::Queues.new.lengths
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, {"Content-Type" => "text/plain", "X-Cascade" => "pass"}, ["Not Found"]] unless action
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 # rubocop:disable Standard/SemanticBlocks
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
- "Content-Type" => "text/html",
317
- "Cache-Control" => "private, no-store",
318
- "Content-Language" => action.locale,
319
- "Content-Security-Policy" => CSP_HEADER
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.strict_encode64(masked_token)
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..-1]
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.strict_decode64(token)
172
+ Base64.urlsafe_decode64(token)
173
173
  end
174
174
 
175
175
  def xor_byte_strings(s1, s2)
@@ -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.load(File.open(file))
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" ? "&uarr;" : "&darr;"
141
141
  end
142
142
 
143
- def workers
144
- @workers ||= Sidekiq::Workers.new
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 redis_connection
168
+ def redis_url
156
169
  Sidekiq.redis do |conn|
157
- conn.connection[:id]
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
- workers.size == 0 ? "idle" : "active"
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.options[:environment] || ENV["APP_ENV"] || ENV["RAILS_ENV"] || ENV["RACK_ENV"] || "development"
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, {"Cache-Control" => "public, max-age=86400"}]] unless ENV["SIDEKIQ_WEB_TESTING"]
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
- root: ASSETS,
152
- cascade: true,
153
- header_rules: rules
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