sidekiq 5.2.10 → 7.2.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 (150) hide show
  1. checksums.yaml +4 -4
  2. data/Changes.md +600 -8
  3. data/LICENSE.txt +9 -0
  4. data/README.md +47 -50
  5. data/bin/sidekiq +22 -3
  6. data/bin/sidekiqload +213 -115
  7. data/bin/sidekiqmon +11 -0
  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 +557 -354
  13. data/lib/sidekiq/capsule.rb +127 -0
  14. data/lib/sidekiq/cli.rb +204 -226
  15. data/lib/sidekiq/client.rb +127 -102
  16. data/lib/sidekiq/component.rb +68 -0
  17. data/lib/sidekiq/config.rb +287 -0
  18. data/lib/sidekiq/deploy.rb +62 -0
  19. data/lib/sidekiq/embedded.rb +61 -0
  20. data/lib/sidekiq/fetch.rb +49 -42
  21. data/lib/sidekiq/job.rb +374 -0
  22. data/lib/sidekiq/job_logger.rb +33 -7
  23. data/lib/sidekiq/job_retry.rb +147 -108
  24. data/lib/sidekiq/job_util.rb +107 -0
  25. data/lib/sidekiq/launcher.rb +203 -105
  26. data/lib/sidekiq/logger.rb +131 -0
  27. data/lib/sidekiq/manager.rb +43 -46
  28. data/lib/sidekiq/metrics/query.rb +155 -0
  29. data/lib/sidekiq/metrics/shared.rb +95 -0
  30. data/lib/sidekiq/metrics/tracking.rb +136 -0
  31. data/lib/sidekiq/middleware/chain.rb +113 -56
  32. data/lib/sidekiq/middleware/current_attributes.rb +95 -0
  33. data/lib/sidekiq/middleware/i18n.rb +7 -7
  34. data/lib/sidekiq/middleware/modules.rb +21 -0
  35. data/lib/sidekiq/monitor.rb +146 -0
  36. data/lib/sidekiq/paginator.rb +28 -16
  37. data/lib/sidekiq/processor.rb +122 -120
  38. data/lib/sidekiq/rails.rb +48 -38
  39. data/lib/sidekiq/redis_client_adapter.rb +111 -0
  40. data/lib/sidekiq/redis_connection.rb +39 -107
  41. data/lib/sidekiq/ring_buffer.rb +29 -0
  42. data/lib/sidekiq/scheduled.rb +111 -49
  43. data/lib/sidekiq/sd_notify.rb +149 -0
  44. data/lib/sidekiq/systemd.rb +24 -0
  45. data/lib/sidekiq/testing/inline.rb +6 -5
  46. data/lib/sidekiq/testing.rb +90 -89
  47. data/lib/sidekiq/transaction_aware_client.rb +44 -0
  48. data/lib/sidekiq/version.rb +3 -1
  49. data/lib/sidekiq/web/action.rb +15 -11
  50. data/lib/sidekiq/web/application.rb +186 -79
  51. data/lib/sidekiq/web/csrf_protection.rb +180 -0
  52. data/lib/sidekiq/web/helpers.rb +154 -115
  53. data/lib/sidekiq/web/router.rb +23 -19
  54. data/lib/sidekiq/web.rb +68 -107
  55. data/lib/sidekiq/worker_compatibility_alias.rb +13 -0
  56. data/lib/sidekiq.rb +92 -182
  57. data/sidekiq.gemspec +25 -16
  58. data/web/assets/images/apple-touch-icon.png +0 -0
  59. data/web/assets/javascripts/application.js +146 -61
  60. data/web/assets/javascripts/base-charts.js +106 -0
  61. data/web/assets/javascripts/chart.min.js +13 -0
  62. data/web/assets/javascripts/chartjs-plugin-annotation.min.js +7 -0
  63. data/web/assets/javascripts/dashboard-charts.js +182 -0
  64. data/web/assets/javascripts/dashboard.js +35 -293
  65. data/web/assets/javascripts/metrics.js +298 -0
  66. data/web/assets/stylesheets/application-dark.css +147 -0
  67. data/web/assets/stylesheets/application-rtl.css +2 -95
  68. data/web/assets/stylesheets/application.css +111 -522
  69. data/web/locales/ar.yml +71 -65
  70. data/web/locales/cs.yml +62 -62
  71. data/web/locales/da.yml +60 -53
  72. data/web/locales/de.yml +65 -53
  73. data/web/locales/el.yml +43 -24
  74. data/web/locales/en.yml +86 -66
  75. data/web/locales/es.yml +70 -54
  76. data/web/locales/fa.yml +65 -65
  77. data/web/locales/fr.yml +83 -62
  78. data/web/locales/gd.yml +99 -0
  79. data/web/locales/he.yml +65 -64
  80. data/web/locales/hi.yml +59 -59
  81. data/web/locales/it.yml +53 -53
  82. data/web/locales/ja.yml +75 -64
  83. data/web/locales/ko.yml +52 -52
  84. data/web/locales/lt.yml +83 -0
  85. data/web/locales/nb.yml +61 -61
  86. data/web/locales/nl.yml +52 -52
  87. data/web/locales/pl.yml +45 -45
  88. data/web/locales/pt-br.yml +83 -55
  89. data/web/locales/pt.yml +51 -51
  90. data/web/locales/ru.yml +68 -63
  91. data/web/locales/sv.yml +53 -53
  92. data/web/locales/ta.yml +60 -60
  93. data/web/locales/uk.yml +62 -61
  94. data/web/locales/ur.yml +64 -64
  95. data/web/locales/vi.yml +83 -0
  96. data/web/locales/zh-cn.yml +43 -16
  97. data/web/locales/zh-tw.yml +42 -8
  98. data/web/views/_footer.erb +6 -3
  99. data/web/views/_job_info.erb +21 -4
  100. data/web/views/_metrics_period_select.erb +12 -0
  101. data/web/views/_nav.erb +1 -1
  102. data/web/views/_paging.erb +2 -0
  103. data/web/views/_poll_link.erb +3 -6
  104. data/web/views/_summary.erb +7 -7
  105. data/web/views/busy.erb +77 -27
  106. data/web/views/dashboard.erb +48 -18
  107. data/web/views/dead.erb +3 -3
  108. data/web/views/filtering.erb +7 -0
  109. data/web/views/layout.erb +3 -1
  110. data/web/views/metrics.erb +91 -0
  111. data/web/views/metrics_for_job.erb +59 -0
  112. data/web/views/morgue.erb +14 -15
  113. data/web/views/queue.erb +33 -24
  114. data/web/views/queues.erb +19 -5
  115. data/web/views/retries.erb +16 -17
  116. data/web/views/retry.erb +3 -3
  117. data/web/views/scheduled.erb +17 -15
  118. metadata +71 -71
  119. data/.circleci/config.yml +0 -61
  120. data/.github/contributing.md +0 -32
  121. data/.github/issue_template.md +0 -11
  122. data/.gitignore +0 -15
  123. data/.travis.yml +0 -11
  124. data/3.0-Upgrade.md +0 -70
  125. data/4.0-Upgrade.md +0 -53
  126. data/5.0-Upgrade.md +0 -56
  127. data/COMM-LICENSE +0 -97
  128. data/Ent-Changes.md +0 -238
  129. data/Gemfile +0 -19
  130. data/LICENSE +0 -9
  131. data/Pro-2.0-Upgrade.md +0 -138
  132. data/Pro-3.0-Upgrade.md +0 -44
  133. data/Pro-4.0-Upgrade.md +0 -35
  134. data/Pro-Changes.md +0 -759
  135. data/Rakefile +0 -9
  136. data/bin/sidekiqctl +0 -20
  137. data/code_of_conduct.md +0 -50
  138. data/lib/generators/sidekiq/worker_generator.rb +0 -49
  139. data/lib/sidekiq/core_ext.rb +0 -1
  140. data/lib/sidekiq/ctl.rb +0 -221
  141. data/lib/sidekiq/delay.rb +0 -42
  142. data/lib/sidekiq/exception_handler.rb +0 -29
  143. data/lib/sidekiq/extensions/action_mailer.rb +0 -57
  144. data/lib/sidekiq/extensions/active_record.rb +0 -40
  145. data/lib/sidekiq/extensions/class_methods.rb +0 -40
  146. data/lib/sidekiq/extensions/generic_proxy.rb +0 -31
  147. data/lib/sidekiq/logging.rb +0 -122
  148. data/lib/sidekiq/middleware/server/active_record.rb +0 -23
  149. data/lib/sidekiq/util.rb +0 -66
  150. data/lib/sidekiq/worker.rb +0 -220
@@ -1,27 +1,46 @@
1
1
  # frozen_string_literal: true
2
- require 'securerandom'
3
- require 'sidekiq'
4
2
 
5
- module Sidekiq
3
+ require "securerandom"
4
+ require "sidekiq"
6
5
 
6
+ module Sidekiq
7
7
  class Testing
8
+ class TestModeAlreadySetError < RuntimeError; end
8
9
  class << self
9
- attr_accessor :__test_mode
10
+ attr_accessor :__global_test_mode
10
11
 
12
+ # Calling without a block sets the global test mode, affecting
13
+ # all threads. Calling with a block only affects the current Thread.
11
14
  def __set_test_mode(mode)
12
15
  if block_given?
13
- current_mode = self.__test_mode
16
+ # Reentrant testing modes will lead to a rat's nest of code which is
17
+ # hard to reason about. You can set the testing mode once globally and
18
+ # you can override that global setting once per-thread.
19
+ raise TestModeAlreadySetError, "Nesting test modes is not supported" if __local_test_mode
20
+
21
+ self.__local_test_mode = mode
14
22
  begin
15
- self.__test_mode = mode
16
23
  yield
17
24
  ensure
18
- self.__test_mode = current_mode
25
+ self.__local_test_mode = nil
19
26
  end
20
27
  else
21
- self.__test_mode = mode
28
+ self.__global_test_mode = mode
22
29
  end
23
30
  end
24
31
 
32
+ def __test_mode
33
+ __local_test_mode || __global_test_mode
34
+ end
35
+
36
+ def __local_test_mode
37
+ Thread.current[:__sidekiq_test_mode]
38
+ end
39
+
40
+ def __local_test_mode=(value)
41
+ Thread.current[:__sidekiq_test_mode] = value
42
+ end
43
+
25
44
  def disable!(&block)
26
45
  __set_test_mode(:disable, &block)
27
46
  end
@@ -35,35 +54,26 @@ module Sidekiq
35
54
  end
36
55
 
37
56
  def enabled?
38
- self.__test_mode != :disable
57
+ __test_mode != :disable
39
58
  end
40
59
 
41
60
  def disabled?
42
- self.__test_mode == :disable
61
+ __test_mode == :disable
43
62
  end
44
63
 
45
64
  def fake?
46
- self.__test_mode == :fake
65
+ __test_mode == :fake
47
66
  end
48
67
 
49
68
  def inline?
50
- self.__test_mode == :inline
69
+ __test_mode == :inline
51
70
  end
52
71
 
53
72
  def server_middleware
54
- @server_chain ||= Middleware::Chain.new
73
+ @server_chain ||= Middleware::Chain.new(Sidekiq.default_configuration)
55
74
  yield @server_chain if block_given?
56
75
  @server_chain
57
76
  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
77
  end
68
78
  end
69
79
 
@@ -73,18 +83,18 @@ module Sidekiq
73
83
  class EmptyQueueError < RuntimeError; end
74
84
 
75
85
  module TestingClient
76
- def raw_push(payloads)
86
+ def atomic_push(conn, payloads)
77
87
  if Sidekiq::Testing.fake?
78
88
  payloads.each do |job|
79
89
  job = Sidekiq.load_json(Sidekiq.dump_json(job))
80
- job.merge!('enqueued_at' => Time.now.to_f) unless job['at']
81
- Queues.push(job['queue'], job['class'], job)
90
+ job["enqueued_at"] = Time.now.to_f unless job["at"]
91
+ Queues.push(job["queue"], job["class"], job)
82
92
  end
83
93
  true
84
94
  elsif Sidekiq::Testing.inline?
85
95
  payloads.each do |job|
86
- klass = Sidekiq::Testing.constantize(job['class'])
87
- job['id'] ||= SecureRandom.hex(12)
96
+ klass = Object.const_get(job["class"])
97
+ job["id"] ||= SecureRandom.hex(12)
88
98
  job_hash = Sidekiq.load_json(Sidekiq.dump_json(job))
89
99
  klass.process_job(job_hash)
90
100
  end
@@ -101,20 +111,20 @@ module Sidekiq
101
111
  ##
102
112
  # The Queues class is only for testing the fake queue implementation.
103
113
  # 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
114
+ # Rspec syntax of change(HardJob.jobs, :size). It keeps a reference
105
115
  # to the array. Because the array was dervied from a filter of the total
106
116
  # jobs enqueued, it appeared as though the array didn't change.
107
117
  #
108
118
  # 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.
119
+ # on the queue, and another with keys of the job type, so the array for
120
+ # HardJob.jobs is a straight reference to a real array.
111
121
  #
112
122
  # Queue-based hash:
113
123
  #
114
124
  # {
115
125
  # "default"=>[
116
126
  # {
117
- # "class"=>"TestTesting::QueueWorker",
127
+ # "class"=>"TestTesting::HardJob",
118
128
  # "args"=>[1, 2],
119
129
  # "retry"=>true,
120
130
  # "queue"=>"default",
@@ -124,12 +134,12 @@ module Sidekiq
124
134
  # ]
125
135
  # }
126
136
  #
127
- # Worker-based hash:
137
+ # Job-based hash:
128
138
  #
129
139
  # {
130
- # "TestTesting::QueueWorker"=>[
140
+ # "TestTesting::HardJob"=>[
131
141
  # {
132
- # "class"=>"TestTesting::QueueWorker",
142
+ # "class"=>"TestTesting::HardJob",
133
143
  # "args"=>[1, 2],
134
144
  # "retry"=>true,
135
145
  # "queue"=>"default",
@@ -144,14 +154,14 @@ module Sidekiq
144
154
  # require 'sidekiq/testing'
145
155
  #
146
156
  # assert_equal 0, Sidekiq::Queues["default"].size
147
- # HardWorker.perform_async(:something)
157
+ # HardJob.perform_async(:something)
148
158
  # assert_equal 1, Sidekiq::Queues["default"].size
149
159
  # assert_equal :something, Sidekiq::Queues["default"].first['args'][0]
150
160
  #
151
- # You can also clear all workers' jobs:
161
+ # You can also clear all jobs:
152
162
  #
153
163
  # assert_equal 0, Sidekiq::Queues["default"].size
154
- # HardWorker.perform_async(:something)
164
+ # HardJob.perform_async(:something)
155
165
  # Sidekiq::Queues.clear_all
156
166
  # assert_equal 0, Sidekiq::Queues["default"].size
157
167
  #
@@ -170,35 +180,36 @@ module Sidekiq
170
180
 
171
181
  def push(queue, klass, job)
172
182
  jobs_by_queue[queue] << job
173
- jobs_by_worker[klass] << job
183
+ jobs_by_class[klass] << job
174
184
  end
175
185
 
176
186
  def jobs_by_queue
177
187
  @jobs_by_queue ||= Hash.new { |hash, key| hash[key] = [] }
178
188
  end
179
189
 
180
- def jobs_by_worker
181
- @jobs_by_worker ||= Hash.new { |hash, key| hash[key] = [] }
190
+ def jobs_by_class
191
+ @jobs_by_class ||= Hash.new { |hash, key| hash[key] = [] }
182
192
  end
193
+ alias_method :jobs_by_worker, :jobs_by_class
183
194
 
184
195
  def delete_for(jid, queue, klass)
185
196
  jobs_by_queue[queue.to_s].delete_if { |job| job["jid"] == jid }
186
- jobs_by_worker[klass].delete_if { |job| job["jid"] == jid }
197
+ jobs_by_class[klass].delete_if { |job| job["jid"] == jid }
187
198
  end
188
199
 
189
200
  def clear_for(queue, klass)
190
- jobs_by_queue[queue].clear
191
- jobs_by_worker[klass].clear
201
+ jobs_by_queue[queue.to_s].clear
202
+ jobs_by_class[klass].clear
192
203
  end
193
204
 
194
205
  def clear_all
195
206
  jobs_by_queue.clear
196
- jobs_by_worker.clear
207
+ jobs_by_class.clear
197
208
  end
198
209
  end
199
210
  end
200
211
 
201
- module Worker
212
+ module Job
202
213
  ##
203
214
  # The Sidekiq testing infrastructure overrides perform_async
204
215
  # so that it does not actually touch the network. Instead it
@@ -212,70 +223,53 @@ module Sidekiq
212
223
  #
213
224
  # require 'sidekiq/testing'
214
225
  #
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
223
- #
224
- # You can also clear and drain all workers' jobs:
225
- #
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
226
+ # assert_equal 0, HardJob.jobs.size
227
+ # HardJob.perform_async(:something)
228
+ # assert_equal 1, HardJob.jobs.size
229
+ # assert_equal :something, HardJob.jobs[0]['args'][0]
234
230
  #
235
- # Sidekiq::Worker.clear_all # or .drain_all
231
+ # You can also clear and drain all job types:
236
232
  #
237
- # assert_equal 0, Sidekiq::Extensions::DelayedMailer.jobs.size
238
- # assert_equal 0, Sidekiq::Extensions::DelayedModel.jobs.size
233
+ # Sidekiq::Job.clear_all # or .drain_all
239
234
  #
240
235
  # This can be useful to make sure jobs don't linger between tests:
241
236
  #
242
237
  # RSpec.configure do |config|
243
238
  # config.before(:each) do
244
- # Sidekiq::Worker.clear_all
239
+ # Sidekiq::Job.clear_all
245
240
  # end
246
241
  # end
247
242
  #
248
243
  # or for acceptance testing, i.e. with cucumber:
249
244
  #
250
245
  # AfterStep do
251
- # Sidekiq::Worker.drain_all
246
+ # Sidekiq::Job.drain_all
252
247
  # end
253
248
  #
254
249
  # When I sign up as "foo@example.com"
255
250
  # Then I should receive a welcome email to "foo@example.com"
256
251
  #
257
252
  module ClassMethods
258
-
259
253
  # Queue for this worker
260
254
  def queue
261
- self.sidekiq_options["queue"]
255
+ get_sidekiq_options["queue"]
262
256
  end
263
257
 
264
258
  # Jobs queued for this worker
265
259
  def jobs
266
- Queues.jobs_by_worker[self.to_s]
260
+ Queues.jobs_by_class[to_s]
267
261
  end
268
262
 
269
263
  # Clear all jobs for this worker
270
264
  def clear
271
- Queues.clear_for(queue, self.to_s)
265
+ Queues.clear_for(queue, to_s)
272
266
  end
273
267
 
274
268
  # Drain and run all jobs for this worker
275
269
  def drain
276
270
  while jobs.any?
277
271
  next_job = jobs.first
278
- Queues.delete_for(next_job["jid"], next_job["queue"], self.to_s)
272
+ Queues.delete_for(next_job["jid"], next_job["queue"], to_s)
279
273
  process_job(next_job)
280
274
  end
281
275
  end
@@ -284,16 +278,16 @@ module Sidekiq
284
278
  def perform_one
285
279
  raise(EmptyQueueError, "perform_one called with empty job queue") if jobs.empty?
286
280
  next_job = jobs.first
287
- Queues.delete_for(next_job["jid"], queue, self.to_s)
281
+ Queues.delete_for(next_job["jid"], queue, to_s)
288
282
  process_job(next_job)
289
283
  end
290
284
 
291
285
  def process_job(job)
292
- worker = new
293
- worker.jid = job['jid']
294
- worker.bid = job['bid'] if worker.respond_to?(:bid=)
295
- Sidekiq::Testing.server_middleware.invoke(worker, job, job['queue']) do
296
- execute_job(worker, job['args'])
286
+ inst = new
287
+ inst.jid = job["jid"]
288
+ inst.bid = job["bid"] if inst.respond_to?(:bid=)
289
+ Sidekiq::Testing.server_middleware.invoke(inst, job, job["queue"]) do
290
+ execute_job(inst, job["args"])
297
291
  end
298
292
  end
299
293
 
@@ -307,27 +301,34 @@ module Sidekiq
307
301
  Queues.jobs_by_queue.values.flatten
308
302
  end
309
303
 
310
- # Clear all queued jobs across all workers
304
+ # Clear all queued jobs
311
305
  def clear_all
312
306
  Queues.clear_all
313
307
  end
314
308
 
315
- # Drain all queued jobs across all workers
309
+ # Drain (execute) all queued jobs
316
310
  def drain_all
317
311
  while jobs.any?
318
- worker_classes = jobs.map { |job| job["class"] }.uniq
312
+ job_classes = jobs.map { |job| job["class"] }.uniq
319
313
 
320
- worker_classes.each do |worker_class|
321
- Sidekiq::Testing.constantize(worker_class).drain
314
+ job_classes.each do |job_class|
315
+ Object.const_get(job_class).drain
322
316
  end
323
317
  end
324
318
  end
325
319
  end
326
320
  end
321
+
322
+ module TestingExtensions
323
+ def jobs_for(klass)
324
+ jobs.select do |job|
325
+ marshalled = job["args"][0]
326
+ marshalled.index(klass.to_s) && YAML.safe_load(marshalled)[0] == klass
327
+ end
328
+ end
329
+ end
327
330
  end
328
331
 
329
- if defined?(::Rails) && Rails.respond_to?(:env) && !Rails.env.test?
330
- puts("**************************************************")
331
- puts("⛔️ WARNING: Sidekiq testing API enabled, but this is not the test environment. Your jobs will not go to Redis.")
332
- puts("**************************************************")
332
+ if defined?(::Rails) && Rails.respond_to?(:env) && !Rails.env.test? && !$TESTING
333
+ warn("⛔️ WARNING: Sidekiq testing API enabled, but this is not the test environment. Your jobs will not go to Redis.", uplevel: 1)
333
334
  end
@@ -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,4 +1,6 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Sidekiq
3
- VERSION = "5.2.10"
4
+ VERSION = "7.2.0"
5
+ MAJOR = 7
4
6
  end
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Sidekiq
4
4
  class WebAction
5
- RACK_SESSION = 'rack.session'
5
+ RACK_SESSION = "rack.session"
6
6
 
7
7
  attr_accessor :env, :block, :type
8
8
 
@@ -15,18 +15,18 @@ 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, {Rack::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, {Web::LOCATION => "#{request.base_url}#{location}"}, []]
23
23
  end
24
24
 
25
25
  def params
26
- indifferent_hash = Hash.new {|hash,key| hash[key.to_s] if Symbol === key }
26
+ indifferent_hash = Hash.new { |hash, key| hash[key.to_s] if Symbol === key }
27
27
 
28
28
  indifferent_hash.merge! request.params
29
- route_params.each {|k,v| indifferent_hash[k.to_s] = v }
29
+ route_params.each { |k, v| indifferent_hash[k.to_s] = v }
30
30
 
31
31
  indifferent_hash
32
32
  end
@@ -40,10 +40,14 @@ module Sidekiq
40
40
  end
41
41
 
42
42
  def erb(content, options = {})
43
- if content.kind_of? Symbol
43
+ if content.is_a? Symbol
44
44
  unless respond_to?(:"_erb_#{content}")
45
45
  src = ERB.new(File.read("#{Web.settings.views}/#{content}.erb")).src
46
- WebAction.class_eval("def _erb_#{content}\n#{src}\n end")
46
+ WebAction.class_eval <<-RUBY, __FILE__, __LINE__ + 1
47
+ def _erb_#{content}
48
+ #{src}
49
+ end
50
+ RUBY
47
51
  end
48
52
  end
49
53
 
@@ -64,22 +68,22 @@ module Sidekiq
64
68
  end
65
69
 
66
70
  def json(payload)
67
- [200, { "Content-Type" => "application/json", "Cache-Control" => "no-cache" }, [Sidekiq.dump_json(payload)]]
71
+ [200, {Rack::CONTENT_TYPE => "application/json", Rack::CACHE_CONTROL => "private, no-store"}, [Sidekiq.dump_json(payload)]]
68
72
  end
69
73
 
70
74
  def initialize(env, block)
71
75
  @_erb = false
72
76
  @env = env
73
77
  @block = block
74
- @@files ||= {}
78
+ @files ||= {}
75
79
  end
76
80
 
77
81
  private
78
82
 
79
83
  def _erb(file, locals)
80
- locals.each {|k, v| define_singleton_method(k){ v } unless (singleton_methods.include? k)} if locals
84
+ locals&.each { |k, v| define_singleton_method(k) { v } unless singleton_methods.include? k }
81
85
 
82
- if file.kind_of?(String)
86
+ if file.is_a?(String)
83
87
  ERB.new(file).result(binding)
84
88
  else
85
89
  send(:"_erb_#{file}")