sidekiq 4.2.4 → 6.4.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 (143) hide show
  1. checksums.yaml +5 -5
  2. data/Changes.md +523 -0
  3. data/LICENSE +3 -3
  4. data/README.md +23 -36
  5. data/bin/sidekiq +26 -2
  6. data/bin/sidekiqload +28 -38
  7. data/bin/sidekiqmon +8 -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/job_spec.rb.erb +6 -0
  11. data/lib/generators/sidekiq/templates/job_test.rb.erb +8 -0
  12. data/lib/sidekiq/api.rb +403 -243
  13. data/lib/sidekiq/cli.rb +230 -211
  14. data/lib/sidekiq/client.rb +53 -64
  15. data/lib/sidekiq/delay.rb +43 -0
  16. data/lib/sidekiq/exception_handler.rb +12 -16
  17. data/lib/sidekiq/extensions/action_mailer.rb +15 -24
  18. data/lib/sidekiq/extensions/active_record.rb +15 -12
  19. data/lib/sidekiq/extensions/class_methods.rb +16 -13
  20. data/lib/sidekiq/extensions/generic_proxy.rb +14 -6
  21. data/lib/sidekiq/fetch.rb +39 -31
  22. data/lib/sidekiq/job.rb +13 -0
  23. data/lib/sidekiq/job_logger.rb +63 -0
  24. data/lib/sidekiq/job_retry.rb +261 -0
  25. data/lib/sidekiq/job_util.rb +65 -0
  26. data/lib/sidekiq/launcher.rb +170 -71
  27. data/lib/sidekiq/logger.rb +166 -0
  28. data/lib/sidekiq/manager.rb +21 -26
  29. data/lib/sidekiq/middleware/chain.rb +20 -8
  30. data/lib/sidekiq/middleware/current_attributes.rb +57 -0
  31. data/lib/sidekiq/middleware/i18n.rb +5 -7
  32. data/lib/sidekiq/monitor.rb +133 -0
  33. data/lib/sidekiq/paginator.rb +18 -14
  34. data/lib/sidekiq/processor.rb +161 -70
  35. data/lib/sidekiq/rails.rb +41 -73
  36. data/lib/sidekiq/redis_connection.rb +65 -20
  37. data/lib/sidekiq/scheduled.rb +95 -34
  38. data/lib/sidekiq/sd_notify.rb +149 -0
  39. data/lib/sidekiq/systemd.rb +24 -0
  40. data/lib/sidekiq/testing/inline.rb +2 -1
  41. data/lib/sidekiq/testing.rb +52 -26
  42. data/lib/sidekiq/util.rb +60 -14
  43. data/lib/sidekiq/version.rb +2 -1
  44. data/lib/sidekiq/web/action.rb +15 -15
  45. data/lib/sidekiq/web/application.rb +115 -89
  46. data/lib/sidekiq/web/csrf_protection.rb +180 -0
  47. data/lib/sidekiq/web/helpers.rb +151 -83
  48. data/lib/sidekiq/web/router.rb +27 -19
  49. data/lib/sidekiq/web.rb +65 -109
  50. data/lib/sidekiq/worker.rb +284 -41
  51. data/lib/sidekiq.rb +93 -60
  52. data/sidekiq.gemspec +24 -22
  53. data/web/assets/images/apple-touch-icon.png +0 -0
  54. data/web/assets/javascripts/application.js +83 -64
  55. data/web/assets/javascripts/dashboard.js +81 -85
  56. data/web/assets/stylesheets/application-dark.css +143 -0
  57. data/web/assets/stylesheets/application-rtl.css +242 -0
  58. data/web/assets/stylesheets/application.css +319 -143
  59. data/web/assets/stylesheets/bootstrap-rtl.min.css +9 -0
  60. data/web/assets/stylesheets/bootstrap.css +2 -2
  61. data/web/locales/ar.yml +87 -0
  62. data/web/locales/de.yml +14 -2
  63. data/web/locales/en.yml +8 -1
  64. data/web/locales/es.yml +22 -5
  65. data/web/locales/fa.yml +80 -0
  66. data/web/locales/fr.yml +10 -3
  67. data/web/locales/he.yml +79 -0
  68. data/web/locales/ja.yml +12 -4
  69. data/web/locales/lt.yml +83 -0
  70. data/web/locales/pl.yml +4 -4
  71. data/web/locales/ru.yml +4 -0
  72. data/web/locales/ur.yml +80 -0
  73. data/web/locales/vi.yml +83 -0
  74. data/web/views/_footer.erb +5 -2
  75. data/web/views/_job_info.erb +4 -3
  76. data/web/views/_nav.erb +4 -18
  77. data/web/views/_paging.erb +1 -1
  78. data/web/views/_poll_link.erb +2 -5
  79. data/web/views/_summary.erb +7 -7
  80. data/web/views/busy.erb +60 -22
  81. data/web/views/dashboard.erb +23 -15
  82. data/web/views/dead.erb +3 -3
  83. data/web/views/layout.erb +14 -3
  84. data/web/views/morgue.erb +19 -12
  85. data/web/views/queue.erb +24 -14
  86. data/web/views/queues.erb +14 -4
  87. data/web/views/retries.erb +22 -13
  88. data/web/views/retry.erb +4 -4
  89. data/web/views/scheduled.erb +7 -4
  90. metadata +49 -198
  91. data/.github/contributing.md +0 -32
  92. data/.github/issue_template.md +0 -4
  93. data/.gitignore +0 -12
  94. data/.travis.yml +0 -12
  95. data/3.0-Upgrade.md +0 -70
  96. data/4.0-Upgrade.md +0 -53
  97. data/COMM-LICENSE +0 -95
  98. data/Ent-Changes.md +0 -146
  99. data/Gemfile +0 -29
  100. data/Pro-2.0-Upgrade.md +0 -138
  101. data/Pro-3.0-Upgrade.md +0 -44
  102. data/Pro-Changes.md +0 -585
  103. data/Rakefile +0 -9
  104. data/bin/sidekiqctl +0 -99
  105. data/code_of_conduct.md +0 -50
  106. data/lib/generators/sidekiq/templates/worker_spec.rb.erb +0 -6
  107. data/lib/generators/sidekiq/templates/worker_test.rb.erb +0 -8
  108. data/lib/generators/sidekiq/worker_generator.rb +0 -49
  109. data/lib/sidekiq/core_ext.rb +0 -106
  110. data/lib/sidekiq/logging.rb +0 -106
  111. data/lib/sidekiq/middleware/server/active_record.rb +0 -13
  112. data/lib/sidekiq/middleware/server/logging.rb +0 -40
  113. data/lib/sidekiq/middleware/server/retry_jobs.rb +0 -205
  114. data/test/config.yml +0 -9
  115. data/test/env_based_config.yml +0 -11
  116. data/test/fake_env.rb +0 -1
  117. data/test/fixtures/en.yml +0 -2
  118. data/test/helper.rb +0 -75
  119. data/test/test_actors.rb +0 -138
  120. data/test/test_api.rb +0 -528
  121. data/test/test_cli.rb +0 -418
  122. data/test/test_client.rb +0 -266
  123. data/test/test_exception_handler.rb +0 -56
  124. data/test/test_extensions.rb +0 -127
  125. data/test/test_fetch.rb +0 -50
  126. data/test/test_launcher.rb +0 -95
  127. data/test/test_logging.rb +0 -35
  128. data/test/test_manager.rb +0 -50
  129. data/test/test_middleware.rb +0 -158
  130. data/test/test_processor.rb +0 -235
  131. data/test/test_rails.rb +0 -22
  132. data/test/test_redis_connection.rb +0 -132
  133. data/test/test_retry.rb +0 -326
  134. data/test/test_retry_exhausted.rb +0 -149
  135. data/test/test_scheduled.rb +0 -115
  136. data/test/test_scheduling.rb +0 -58
  137. data/test/test_sidekiq.rb +0 -107
  138. data/test/test_testing.rb +0 -143
  139. data/test/test_testing_fake.rb +0 -357
  140. data/test/test_testing_inline.rb +0 -94
  141. data/test/test_util.rb +0 -13
  142. data/test/test_web.rb +0 -726
  143. data/test/test_web_helpers.rb +0 -54
data/test/test_retry.rb DELETED
@@ -1,326 +0,0 @@
1
- # frozen_string_literal: true
2
- # encoding: utf-8
3
- require_relative 'helper'
4
- require 'sidekiq/scheduled'
5
- require 'sidekiq/middleware/server/retry_jobs'
6
-
7
- class TestRetry < Sidekiq::Test
8
- describe 'middleware' do
9
- class SomeWorker
10
- include Sidekiq::Worker
11
- end
12
-
13
- before do
14
- Sidekiq.redis {|c| c.flushdb }
15
- end
16
-
17
- def worker
18
- @worker ||= SomeWorker.new
19
- end
20
-
21
- def handler(options={})
22
- @handler ||= Sidekiq::Middleware::Server::RetryJobs.new(options)
23
- end
24
-
25
- def job(options={})
26
- @job ||= { 'class' => 'Bob', 'args' => [1,2,'foo'], 'retry' => true }.merge(options)
27
- end
28
-
29
- it 'allows disabling retry' do
30
- assert_raises RuntimeError do
31
- handler.call(worker, job('retry' => false), 'default') do
32
- raise "kerblammo!"
33
- end
34
- end
35
- assert_equal 0, Sidekiq::RetrySet.new.size
36
- end
37
-
38
- it 'allows a numeric retry' do
39
- assert_raises RuntimeError do
40
- handler.call(worker, job('retry' => 2), 'default') do
41
- raise "kerblammo!"
42
- end
43
- end
44
- assert_equal 1, Sidekiq::RetrySet.new.size
45
- assert_equal 0, Sidekiq::DeadSet.new.size
46
- end
47
-
48
- it 'allows 0 retry => no retry and dead queue' do
49
- assert_raises RuntimeError do
50
- handler.call(worker, job('retry' => 0), 'default') do
51
- raise "kerblammo!"
52
- end
53
- end
54
- assert_equal 0, Sidekiq::RetrySet.new.size
55
- assert_equal 1, Sidekiq::DeadSet.new.size
56
- end
57
-
58
- it 'handles zany characters in error message, #1705' do
59
- skip 'skipped! test requires ruby 2.1+' if RUBY_VERSION <= '2.1.0'
60
-
61
- assert_raises RuntimeError do
62
- handler.call(worker, job, 'default') do
63
- raise "kerblammo! #{195.chr}"
64
- end
65
- end
66
- assert_equal "kerblammo! �", job["error_message"]
67
- end
68
-
69
-
70
- it 'allows a max_retries option in initializer' do
71
- max_retries = 7
72
- 1.upto(max_retries + 1) do
73
- assert_raises RuntimeError do
74
- handler(:max_retries => max_retries).call(worker, job, 'default') do
75
- raise "kerblammo!"
76
- end
77
- end
78
- end
79
-
80
- assert_equal max_retries, Sidekiq::RetrySet.new.size
81
- assert_equal 1, Sidekiq::DeadSet.new.size
82
- end
83
-
84
- it 'saves backtraces' do
85
- c = nil
86
- assert_raises RuntimeError do
87
- handler.call(worker, job('backtrace' => true), 'default') do
88
- c = caller(0); raise "kerblammo!"
89
- end
90
- end
91
- assert job["error_backtrace"]
92
- assert_equal c[0], job["error_backtrace"][0]
93
- end
94
-
95
- it 'saves partial backtraces' do
96
- c = nil
97
- assert_raises RuntimeError do
98
- handler.call(worker, job('backtrace' => 3), 'default') do
99
- c = caller(0)[0...3]; raise "kerblammo!"
100
- end
101
- end
102
- assert job["error_backtrace"]
103
- assert_equal c, job["error_backtrace"]
104
- assert_equal 3, c.size
105
- end
106
-
107
- it 'handles a new failed message' do
108
- assert_raises RuntimeError do
109
- handler.call(worker, job, 'default') do
110
- raise "kerblammo!"
111
- end
112
- end
113
- assert_equal 'default', job["queue"]
114
- assert_equal 'kerblammo!', job["error_message"]
115
- assert_equal 'RuntimeError', job["error_class"]
116
- assert_equal 0, job["retry_count"]
117
- refute job["error_backtrace"]
118
- assert job["failed_at"]
119
- end
120
-
121
- it 'shuts down without retrying work-in-progress, which will resume' do
122
- rs = Sidekiq::RetrySet.new
123
- assert_equal 0, rs.size
124
- msg = { 'class' => 'Bob', 'args' => [1,2,'foo'], 'retry' => true }
125
- assert_raises Sidekiq::Shutdown do
126
- handler.call(worker, msg, 'default') do
127
- raise Sidekiq::Shutdown
128
- end
129
- end
130
- assert_equal 0, rs.size
131
- end
132
-
133
- it 'shuts down cleanly when shutdown causes exception' do
134
- skip('Not supported in Ruby < 2.1.0') if RUBY_VERSION < '2.1.0'
135
-
136
- rs = Sidekiq::RetrySet.new
137
- assert_equal 0, rs.size
138
- msg = { 'class' => 'Bob', 'args' => [1,2,'foo'], 'retry' => true }
139
- assert_raises Sidekiq::Shutdown do
140
- handler.call(worker, msg, 'default') do
141
- begin
142
- raise Sidekiq::Shutdown
143
- rescue Interrupt
144
- raise "kerblammo!"
145
- end
146
- end
147
- end
148
- assert_equal 0, rs.size
149
- end
150
-
151
- it 'shuts down cleanly when shutdown causes chained exceptions' do
152
- skip('Not supported in Ruby < 2.1.0') if RUBY_VERSION < '2.1.0'
153
-
154
- rs = Sidekiq::RetrySet.new
155
- assert_equal 0, rs.size
156
- assert_raises Sidekiq::Shutdown do
157
- handler.call(worker, job, 'default') do
158
- begin
159
- raise Sidekiq::Shutdown
160
- rescue Interrupt
161
- begin
162
- raise "kerblammo!"
163
- rescue
164
- raise "kablooie!"
165
- end
166
- end
167
- end
168
- end
169
- assert_equal 0, rs.size
170
- end
171
-
172
- it 'allows a retry queue' do
173
- assert_raises RuntimeError do
174
- handler.call(worker, job("retry_queue" => 'retryx'), 'default') do
175
- raise "kerblammo!"
176
- end
177
- end
178
- assert_equal 'retryx', job["queue"]
179
- assert_equal 'kerblammo!', job["error_message"]
180
- assert_equal 'RuntimeError', job["error_class"]
181
- assert_equal 0, job["retry_count"]
182
- refute job["error_backtrace"]
183
- assert job["failed_at"]
184
- end
185
-
186
- it 'handles a recurring failed message' do
187
- now = Time.now.to_f
188
- msg = {"queue"=>"default", "error_message"=>"kerblammo!", "error_class"=>"RuntimeError", "failed_at"=>now, "retry_count"=>10}
189
- assert_raises RuntimeError do
190
- handler.call(worker, job(msg), 'default') do
191
- raise "kerblammo!"
192
- end
193
- end
194
- assert_equal 'default', job["queue"]
195
- assert_equal 'kerblammo!', job["error_message"]
196
- assert_equal 'RuntimeError', job["error_class"]
197
- assert_equal 11, job["retry_count"]
198
- assert job["failed_at"]
199
- end
200
-
201
- it 'throws away old messages after too many retries (using the default)' do
202
- q = Sidekiq::Queue.new
203
- rs = Sidekiq::RetrySet.new
204
- ds = Sidekiq::DeadSet.new
205
- assert_equal 0, q.size
206
- assert_equal 0, rs.size
207
- assert_equal 0, ds.size
208
- now = Time.now.to_f
209
- msg = {"queue"=>"default", "error_message"=>"kerblammo!", "error_class"=>"RuntimeError", "failed_at"=>now, "retry_count"=>25}
210
- assert_raises RuntimeError do
211
- handler.call(worker, job(msg), 'default') do
212
- raise "kerblammo!"
213
- end
214
- end
215
- assert_equal 0, q.size
216
- assert_equal 0, rs.size
217
- assert_equal 1, ds.size
218
- end
219
-
220
- describe "custom retry delay" do
221
- before do
222
- @old_logger = Sidekiq.logger
223
- @tmp_log_path = '/tmp/sidekiq-retries.log'
224
- Sidekiq.logger = Logger.new(@tmp_log_path)
225
- end
226
-
227
- after do
228
- Sidekiq.logger = @old_logger
229
- Sidekiq.options.delete(:logfile)
230
- File.unlink @tmp_log_path if File.exist?(@tmp_log_path)
231
- end
232
-
233
- class CustomWorkerWithoutException
234
- include Sidekiq::Worker
235
-
236
- sidekiq_retry_in do |count|
237
- count * 2
238
- end
239
- end
240
-
241
- class CustomWorkerWithException
242
- include Sidekiq::Worker
243
-
244
- sidekiq_retry_in do |count, exception|
245
- case exception
246
- when ArgumentError
247
- count * 4
248
- else
249
- count * 2
250
- end
251
- end
252
- end
253
-
254
- class ErrorWorker
255
- include Sidekiq::Worker
256
-
257
- sidekiq_retry_in do |count|
258
- count / 0
259
- end
260
- end
261
-
262
- it "retries with a default delay" do
263
- refute_equal 4, handler.__send__(:delay_for, worker, 2, StandardError.new)
264
- end
265
-
266
- it "retries with a custom delay and exception 1" do
267
- assert_equal 8, handler.__send__(:delay_for, CustomWorkerWithException, 2, ArgumentError.new)
268
- end
269
-
270
- it "retries with a custom delay and exception 2" do
271
- assert_equal 4, handler.__send__(:delay_for, CustomWorkerWithException, 2, StandardError.new)
272
- end
273
-
274
- it "retries with a custom delay without exception" do
275
- assert_equal 4, handler.__send__(:delay_for, CustomWorkerWithoutException, 2, StandardError.new)
276
- end
277
-
278
- it "falls back to the default retry on exception" do
279
- refute_equal 4, handler.__send__(:delay_for, ErrorWorker, 2, StandardError.new)
280
- assert_match(/Failure scheduling retry using the defined `sidekiq_retry_in`/,
281
- File.read(@tmp_log_path), 'Log entry missing for sidekiq_retry_in')
282
- end
283
- end
284
-
285
- describe 'handles errors withouth cause' do
286
- before do
287
- @error = nil
288
- begin
289
- raise ::StandardError, 'Error'
290
- rescue ::StandardError => e
291
- @error = e
292
- end
293
- end
294
-
295
- it "does not recurse infinitely checking if it's a shutdown" do
296
- assert(!Sidekiq::Middleware::Server::RetryJobs.new.send(
297
- :exception_caused_by_shutdown?, @error))
298
- end
299
- end
300
-
301
- describe 'handles errors with circular causes' do
302
- before do
303
- @error = nil
304
- begin
305
- begin
306
- raise ::StandardError, 'Error 1'
307
- rescue ::StandardError => e1
308
- begin
309
- raise ::StandardError, 'Error 2'
310
- rescue ::StandardError
311
- raise e1
312
- end
313
- end
314
- rescue ::StandardError => e
315
- @error = e
316
- end
317
- end
318
-
319
- it "does not recurse infinitely checking if it's a shutdown" do
320
- assert(!Sidekiq::Middleware::Server::RetryJobs.new.send(
321
- :exception_caused_by_shutdown?, @error))
322
- end
323
- end
324
- end
325
-
326
- end
@@ -1,149 +0,0 @@
1
- # encoding: utf-8
2
- require_relative 'helper'
3
- require 'sidekiq/middleware/server/retry_jobs'
4
-
5
- class TestRetryExhausted < Sidekiq::Test
6
- describe 'sidekiq_retries_exhausted' do
7
- class NewWorker
8
- include Sidekiq::Worker
9
-
10
- class_attribute :exhausted_called, :exhausted_job, :exhausted_exception
11
-
12
- sidekiq_retries_exhausted do |job, e|
13
- self.exhausted_called = true
14
- self.exhausted_job = job
15
- self.exhausted_exception = e
16
- end
17
- end
18
-
19
- class OldWorker
20
- include Sidekiq::Worker
21
-
22
- class_attribute :exhausted_called, :exhausted_job, :exhausted_exception
23
-
24
- sidekiq_retries_exhausted do |job|
25
- self.exhausted_called = true
26
- self.exhausted_job = job
27
- end
28
- end
29
-
30
- def cleanup
31
- [NewWorker, OldWorker].each do |worker_class|
32
- worker_class.exhausted_called = nil
33
- worker_class.exhausted_job = nil
34
- worker_class.exhausted_exception = nil
35
- end
36
- end
37
-
38
- before do
39
- cleanup
40
- end
41
-
42
- after do
43
- cleanup
44
- end
45
-
46
- def new_worker
47
- @new_worker ||= NewWorker.new
48
- end
49
-
50
- def old_worker
51
- @old_worker ||= OldWorker.new
52
- end
53
-
54
- def handler(options={})
55
- @handler ||= Sidekiq::Middleware::Server::RetryJobs.new(options)
56
- end
57
-
58
- def job(options={})
59
- @job ||= {'class' => 'Bob', 'args' => [1, 2, 'foo']}.merge(options)
60
- end
61
-
62
- it 'does not run exhausted block when job successful on first run' do
63
- handler.call(new_worker, job('retry' => 2), 'default') do
64
- # successful
65
- end
66
-
67
- refute NewWorker.exhausted_called?
68
- end
69
-
70
- it 'does not run exhausted block when job successful on last retry' do
71
- handler.call(new_worker, job('retry_count' => 0, 'retry' => 1), 'default') do
72
- # successful
73
- end
74
-
75
- refute NewWorker.exhausted_called?
76
- end
77
-
78
- it 'does not run exhausted block when retries not exhausted yet' do
79
- assert_raises RuntimeError do
80
- handler.call(new_worker, job('retry' => 1), 'default') do
81
- raise 'kerblammo!'
82
- end
83
- end
84
-
85
- refute NewWorker.exhausted_called?
86
- end
87
-
88
- it 'runs exhausted block when retries exhausted' do
89
- assert_raises RuntimeError do
90
- handler.call(new_worker, job('retry_count' => 0, 'retry' => 1), 'default') do
91
- raise 'kerblammo!'
92
- end
93
- end
94
-
95
- assert NewWorker.exhausted_called?
96
- end
97
-
98
-
99
- it 'passes job and exception to retries exhausted block' do
100
- raised_error = assert_raises RuntimeError do
101
- handler.call(new_worker, job('retry_count' => 0, 'retry' => 1), 'default') do
102
- raise 'kerblammo!'
103
- end
104
- end
105
-
106
- assert new_worker.exhausted_called?
107
- assert_equal raised_error.message, new_worker.exhausted_job['error_message']
108
- assert_equal raised_error, new_worker.exhausted_exception
109
- end
110
-
111
- it 'passes job to retries exhausted block' do
112
- raised_error = assert_raises RuntimeError do
113
- handler.call(old_worker, job('retry_count' => 0, 'retry' => 1), 'default') do
114
- raise 'kerblammo!'
115
- end
116
- end
117
-
118
- assert old_worker.exhausted_called?
119
- assert_equal raised_error.message, old_worker.exhausted_job['error_message']
120
- assert_equal nil, new_worker.exhausted_exception
121
- end
122
-
123
- it 'allows a global default handler' do
124
- begin
125
- class Foobar
126
- include Sidekiq::Worker
127
- end
128
-
129
- exhausted_job = nil
130
- exhausted_exception = nil
131
- Sidekiq.default_retries_exhausted = lambda do |job, ex|
132
- exhausted_job = job
133
- exhausted_exception = ex
134
- end
135
- f = Foobar.new
136
- raised_error = assert_raises RuntimeError do
137
- handler.call(f, job('retry_count' => 0, 'retry' => 1), 'default') do
138
- raise 'kerblammo!'
139
- end
140
- end
141
-
142
- assert exhausted_job
143
- assert_equal raised_error, exhausted_exception
144
- ensure
145
- Sidekiq.default_retries_exhausted = nil
146
- end
147
- end
148
- end
149
- end
@@ -1,115 +0,0 @@
1
- # frozen_string_literal: true
2
- require_relative 'helper'
3
- require 'sidekiq/scheduled'
4
-
5
- class TestScheduled < Sidekiq::Test
6
- class ScheduledWorker
7
- include Sidekiq::Worker
8
- def perform(x)
9
- end
10
- end
11
-
12
- describe 'poller' do
13
- before do
14
- Sidekiq.redis{|c| c.flushdb}
15
- @error_1 = { 'class' => ScheduledWorker.name, 'args' => [0], 'queue' => 'queue_1' }
16
- @error_2 = { 'class' => ScheduledWorker.name, 'args' => [1], 'queue' => 'queue_2' }
17
- @error_3 = { 'class' => ScheduledWorker.name, 'args' => [2], 'queue' => 'queue_3' }
18
- @future_1 = { 'class' => ScheduledWorker.name, 'args' => [3], 'queue' => 'queue_4' }
19
- @future_2 = { 'class' => ScheduledWorker.name, 'args' => [4], 'queue' => 'queue_5' }
20
- @future_3 = { 'class' => ScheduledWorker.name, 'args' => [5], 'queue' => 'queue_6' }
21
-
22
- @retry = Sidekiq::RetrySet.new
23
- @scheduled = Sidekiq::ScheduledSet.new
24
- @poller = Sidekiq::Scheduled::Poller.new
25
- end
26
-
27
- class Stopper
28
- def call(worker_class, job, queue, r)
29
- yield if job['args'].first.odd?
30
- end
31
- end
32
-
33
- it 'executes client middleware' do
34
- Sidekiq.client_middleware.add Stopper
35
- begin
36
- @retry.schedule (Time.now - 60).to_f, @error_1
37
- @retry.schedule (Time.now - 60).to_f, @error_2
38
- @scheduled.schedule (Time.now - 60).to_f, @future_2
39
- @scheduled.schedule (Time.now - 60).to_f, @future_3
40
-
41
- @poller.enqueue
42
-
43
- assert_equal 0, Sidekiq::Queue.new("queue_1").size
44
- assert_equal 1, Sidekiq::Queue.new("queue_2").size
45
- assert_equal 0, Sidekiq::Queue.new("queue_5").size
46
- assert_equal 1, Sidekiq::Queue.new("queue_6").size
47
- ensure
48
- Sidekiq.client_middleware.remove Stopper
49
- end
50
- end
51
-
52
- it 'should empty the retry and scheduled queues up to the current time' do
53
- created_time = Time.new(2013, 2, 3)
54
- enqueued_time = Time.new(2013, 2, 4)
55
-
56
- Time.stub(:now, created_time) do
57
- @retry.schedule (enqueued_time - 60).to_f, @error_1.merge!('created_at' => created_time.to_f)
58
- @retry.schedule (enqueued_time - 50).to_f, @error_2.merge!('created_at' => created_time.to_f)
59
- @retry.schedule (enqueued_time + 60).to_f, @error_3.merge!('created_at' => created_time.to_f)
60
- @scheduled.schedule (enqueued_time - 60).to_f, @future_1.merge!('created_at' => created_time.to_f)
61
- @scheduled.schedule (enqueued_time - 50).to_f, @future_2.merge!('created_at' => created_time.to_f)
62
- @scheduled.schedule (enqueued_time + 60).to_f, @future_3.merge!('created_at' => created_time.to_f)
63
- end
64
-
65
- Time.stub(:now, enqueued_time) do
66
- @poller.enqueue
67
-
68
- Sidekiq.redis do |conn|
69
- %w(queue:queue_1 queue:queue_2 queue:queue_4 queue:queue_5).each do |queue_name|
70
- assert_equal 1, conn.llen(queue_name)
71
- job = Sidekiq.load_json(conn.lrange(queue_name, 0, -1)[0])
72
- assert_equal enqueued_time.to_f, job['enqueued_at']
73
- assert_equal created_time.to_f, job['created_at']
74
- end
75
- end
76
-
77
- assert_equal 1, @retry.size
78
- assert_equal 1, @scheduled.size
79
- end
80
- end
81
-
82
- def with_sidekiq_option(name, value)
83
- _original, Sidekiq.options[name] = Sidekiq.options[name], value
84
- begin
85
- yield
86
- ensure
87
- Sidekiq.options[name] = _original
88
- end
89
- end
90
-
91
- it 'generates random intervals that target a configured average' do
92
- with_sidekiq_option(:poll_interval_average, 10) do
93
- i = 500
94
- intervals = Array.new(i){ @poller.send(:random_poll_interval) }
95
-
96
- assert intervals.all?{|x| x >= 5}
97
- assert intervals.all?{|x| x <= 15}
98
- assert_in_delta 10, intervals.reduce(&:+).to_f / i, 0.5
99
- end
100
- end
101
-
102
- it 'calculates an average poll interval based on the number of known Sidekiq processes' do
103
- with_sidekiq_option(:average_scheduled_poll_interval, 10) do
104
- 3.times do |i|
105
- Sidekiq.redis do |conn|
106
- conn.sadd("processes", "process-#{i}")
107
- conn.hset("process-#{i}", "info", nil)
108
- end
109
- end
110
-
111
- assert_equal 30, @poller.send(:scaled_poll_interval)
112
- end
113
- end
114
- end
115
- end
@@ -1,58 +0,0 @@
1
- # frozen_string_literal: true
2
- require_relative 'helper'
3
- require 'sidekiq/scheduled'
4
-
5
- class TestScheduling < Sidekiq::Test
6
- describe 'middleware' do
7
- class ScheduledWorker
8
- include Sidekiq::Worker
9
- sidekiq_options :queue => :custom_queue
10
- def perform(x)
11
- end
12
- end
13
-
14
- # Assume we can pass any class as time to perform_in
15
- class TimeDuck
16
- def to_f; 42.0 end
17
- end
18
-
19
- it 'schedules jobs' do
20
- ss = Sidekiq::ScheduledSet.new
21
- ss.clear
22
-
23
- assert_equal 0, ss.size
24
-
25
- assert ScheduledWorker.perform_in(600, 'mike')
26
- assert_equal 1, ss.size
27
-
28
- assert ScheduledWorker.perform_in(1.month, 'mike')
29
- assert_equal 2, ss.size
30
-
31
- assert ScheduledWorker.perform_in(5.days.from_now, 'mike')
32
- assert_equal 3, ss.size
33
-
34
- q = Sidekiq::Queue.new("custom_queue")
35
- qs = q.size
36
- assert ScheduledWorker.perform_in(-300, 'mike')
37
- assert_equal 3, ss.size
38
- assert_equal qs+1, q.size
39
-
40
- assert Sidekiq::Client.push_bulk('class' => ScheduledWorker, 'args' => [['mike'], ['mike']], 'at' => 600)
41
- assert_equal 5, ss.size
42
-
43
- assert ScheduledWorker.perform_in(TimeDuck.new, 'samwise')
44
- assert_equal 6, ss.size
45
- end
46
-
47
- it 'removes the enqueued_at field when scheduling' do
48
- ss = Sidekiq::ScheduledSet.new
49
- ss.clear
50
-
51
- assert ScheduledWorker.perform_in(1.month, 'mike')
52
- job = ss.first
53
- assert job['created_at']
54
- refute job['enqueued_at']
55
- end
56
- end
57
-
58
- end