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_actors.rb DELETED
@@ -1,138 +0,0 @@
1
- # frozen_string_literal: true
2
- require_relative 'helper'
3
- require 'sidekiq/cli'
4
- require 'sidekiq/fetch'
5
- require 'sidekiq/scheduled'
6
- require 'sidekiq/processor'
7
-
8
- class TestActors < Sidekiq::Test
9
- class JoeWorker
10
- include Sidekiq::Worker
11
- def perform(slp)
12
- raise "boom" if slp == "boom"
13
- sleep(slp) if slp > 0
14
- $count += 1
15
- end
16
- end
17
-
18
- describe 'threads' do
19
- before do
20
- Sidekiq.redis {|c| c.flushdb}
21
- end
22
-
23
- describe 'scheduler' do
24
- it 'can start and stop' do
25
- f = Sidekiq::Scheduled::Poller.new
26
- f.start
27
- f.terminate
28
- end
29
-
30
- it 'can schedule' do
31
- ss = Sidekiq::ScheduledSet.new
32
- q = Sidekiq::Queue.new
33
-
34
- JoeWorker.perform_in(0.01, 0)
35
-
36
- assert_equal 0, q.size
37
- assert_equal 1, ss.size
38
-
39
- sleep 0.015
40
- s = Sidekiq::Scheduled::Poller.new
41
- s.enqueue
42
- assert_equal 1, q.size
43
- assert_equal 0, ss.size
44
- s.terminate
45
- end
46
- end
47
-
48
- describe 'processor' do
49
- before do
50
- $count = 0
51
- end
52
-
53
- it 'can start and stop' do
54
- f = Sidekiq::Processor.new(Mgr.new)
55
- f.terminate
56
- end
57
-
58
- class Mgr
59
- attr_reader :latest_error
60
- attr_reader :mutex
61
- attr_reader :cond
62
- def initialize
63
- @mutex = ::Mutex.new
64
- @cond = ::ConditionVariable.new
65
- end
66
- def processor_died(inst, err)
67
- @latest_error = err
68
- @mutex.synchronize do
69
- @cond.signal
70
- end
71
- end
72
- def processor_stopped(inst)
73
- @mutex.synchronize do
74
- @cond.signal
75
- end
76
- end
77
- def options
78
- { :concurrency => 3, :queues => ['default'] }
79
- end
80
- end
81
-
82
- it 'can process' do
83
- mgr = Mgr.new
84
-
85
- p = Sidekiq::Processor.new(mgr)
86
- JoeWorker.perform_async(0)
87
-
88
- a = $count
89
- p.process_one
90
- b = $count
91
- assert_equal a + 1, b
92
- end
93
-
94
- it 'deals with errors' do
95
- mgr = Mgr.new
96
-
97
- p = Sidekiq::Processor.new(mgr)
98
- JoeWorker.perform_async("boom")
99
- q = Sidekiq::Queue.new
100
- assert_equal 1, q.size
101
-
102
- a = $count
103
- mgr.mutex.synchronize do
104
- p.start
105
- mgr.cond.wait(mgr.mutex)
106
- end
107
- b = $count
108
- assert_equal a, b
109
-
110
- sleep 0.001
111
- assert_equal false, p.thread.status
112
- p.terminate(true)
113
- refute_nil mgr.latest_error
114
- assert_equal RuntimeError, mgr.latest_error.class
115
- end
116
-
117
- it 'gracefully kills' do
118
- mgr = Mgr.new
119
-
120
- p = Sidekiq::Processor.new(mgr)
121
- JoeWorker.perform_async(1)
122
- q = Sidekiq::Queue.new
123
- assert_equal 1, q.size
124
-
125
- a = $count
126
- p.start
127
- sleep(0.02)
128
- p.terminate
129
- p.kill(true)
130
-
131
- b = $count
132
- assert_equal a, b
133
- assert_equal false, p.thread.status
134
- refute mgr.latest_error, mgr.latest_error.to_s
135
- end
136
- end
137
- end
138
- end
data/test/test_api.rb DELETED
@@ -1,528 +0,0 @@
1
- # frozen_string_literal: true
2
- require_relative 'helper'
3
- require 'sidekiq/api'
4
- require 'active_job'
5
- require 'action_mailer'
6
-
7
- class TestApi < Sidekiq::Test
8
- describe 'api' do
9
- before do
10
- Sidekiq.redis {|c| c.flushdb }
11
- end
12
-
13
- describe "stats" do
14
- it "is initially zero" do
15
- s = Sidekiq::Stats.new
16
- assert_equal 0, s.processed
17
- assert_equal 0, s.failed
18
- assert_equal 0, s.enqueued
19
- end
20
-
21
- describe "processed" do
22
- it "returns number of processed jobs" do
23
- Sidekiq.redis { |conn| conn.set("stat:processed", 5) }
24
- s = Sidekiq::Stats.new
25
- assert_equal 5, s.processed
26
- end
27
- end
28
-
29
- describe "failed" do
30
- it "returns number of failed jobs" do
31
- Sidekiq.redis { |conn| conn.set("stat:failed", 5) }
32
- s = Sidekiq::Stats.new
33
- assert_equal 5, s.failed
34
- end
35
- end
36
-
37
- describe "reset" do
38
- before do
39
- Sidekiq.redis do |conn|
40
- conn.set('stat:processed', 5)
41
- conn.set('stat:failed', 10)
42
- end
43
- end
44
-
45
- it 'will reset all stats by default' do
46
- Sidekiq::Stats.new.reset
47
- s = Sidekiq::Stats.new
48
- assert_equal 0, s.failed
49
- assert_equal 0, s.processed
50
- end
51
-
52
- it 'can reset individual stats' do
53
- Sidekiq::Stats.new.reset('failed')
54
- s = Sidekiq::Stats.new
55
- assert_equal 0, s.failed
56
- assert_equal 5, s.processed
57
- end
58
-
59
- it 'can accept anything that responds to #to_s' do
60
- Sidekiq::Stats.new.reset(:failed)
61
- s = Sidekiq::Stats.new
62
- assert_equal 0, s.failed
63
- assert_equal 5, s.processed
64
- end
65
-
66
- it 'ignores anything other than "failed" or "processed"' do
67
- Sidekiq::Stats.new.reset((1..10).to_a, ['failed'])
68
- s = Sidekiq::Stats.new
69
- assert_equal 0, s.failed
70
- assert_equal 5, s.processed
71
- end
72
- end
73
-
74
- describe "queues" do
75
- it "is initially empty" do
76
- s = Sidekiq::Stats::Queues.new
77
- assert_equal 0, s.lengths.size
78
- end
79
-
80
- it "returns a hash of queue and size in order" do
81
- Sidekiq.redis do |conn|
82
- conn.rpush 'queue:foo', '{}'
83
- conn.sadd 'queues', 'foo'
84
-
85
- 3.times { conn.rpush 'queue:bar', '{}' }
86
- conn.sadd 'queues', 'bar'
87
- end
88
-
89
- s = Sidekiq::Stats::Queues.new
90
- assert_equal ({ "foo" => 1, "bar" => 3 }), s.lengths
91
- assert_equal "bar", s.lengths.first.first
92
-
93
- assert_equal Sidekiq::Stats.new.queues, Sidekiq::Stats::Queues.new.lengths
94
- end
95
- end
96
-
97
- describe "enqueued" do
98
- it "returns total enqueued jobs" do
99
- Sidekiq.redis do |conn|
100
- conn.rpush 'queue:foo', '{}'
101
- conn.sadd 'queues', 'foo'
102
-
103
- 3.times { conn.rpush 'queue:bar', '{}' }
104
- conn.sadd 'queues', 'bar'
105
- end
106
-
107
- s = Sidekiq::Stats.new
108
- assert_equal 4, s.enqueued
109
- end
110
- end
111
-
112
- describe "over time" do
113
- before do
114
- require 'active_support/core_ext/time/conversions'
115
- @before = Time::DATE_FORMATS[:default]
116
- Time::DATE_FORMATS[:default] = "%d/%m/%Y %H:%M:%S"
117
- end
118
-
119
- after do
120
- Time::DATE_FORMATS[:default] = @before
121
- end
122
-
123
- describe "processed" do
124
- it 'retrieves hash of dates' do
125
- Sidekiq.redis do |c|
126
- c.incrby("stat:processed:2012-12-24", 4)
127
- c.incrby("stat:processed:2012-12-25", 1)
128
- c.incrby("stat:processed:2012-12-26", 6)
129
- c.incrby("stat:processed:2012-12-27", 2)
130
- end
131
- Time.stub(:now, Time.parse("2012-12-26 1:00:00 -0500")) do
132
- s = Sidekiq::Stats::History.new(2)
133
- assert_equal({ "2012-12-26" => 6, "2012-12-25" => 1 }, s.processed)
134
-
135
- s = Sidekiq::Stats::History.new(3)
136
- assert_equal({ "2012-12-26" => 6, "2012-12-25" => 1, "2012-12-24" => 4 }, s.processed)
137
-
138
- s = Sidekiq::Stats::History.new(2, Date.parse("2012-12-25"))
139
- assert_equal({ "2012-12-25" => 1, "2012-12-24" => 4 }, s.processed)
140
- end
141
- end
142
- end
143
-
144
- describe "failed" do
145
- it 'retrieves hash of dates' do
146
- Sidekiq.redis do |c|
147
- c.incrby("stat:failed:2012-12-24", 4)
148
- c.incrby("stat:failed:2012-12-25", 1)
149
- c.incrby("stat:failed:2012-12-26", 6)
150
- c.incrby("stat:failed:2012-12-27", 2)
151
- end
152
- Time.stub(:now, Time.parse("2012-12-26 1:00:00 -0500")) do
153
- s = Sidekiq::Stats::History.new(2)
154
- assert_equal ({ "2012-12-26" => 6, "2012-12-25" => 1 }), s.failed
155
-
156
- s = Sidekiq::Stats::History.new(3)
157
- assert_equal ({ "2012-12-26" => 6, "2012-12-25" => 1, "2012-12-24" => 4 }), s.failed
158
-
159
- s = Sidekiq::Stats::History.new(2, Date.parse("2012-12-25"))
160
- assert_equal ({ "2012-12-25" => 1, "2012-12-24" => 4 }), s.failed
161
- end
162
- end
163
- end
164
- end
165
- end
166
-
167
- describe 'with an empty database' do
168
- it 'shows queue as empty' do
169
- q = Sidekiq::Queue.new
170
- assert_equal 0, q.size
171
- assert_equal 0, q.latency
172
- end
173
-
174
- before do
175
- ActiveJob::Base.queue_adapter = :sidekiq
176
- ActiveJob::Base.logger = nil
177
-
178
- class ApiMailer < ActionMailer::Base
179
- def test_email(*)
180
- end
181
- end
182
-
183
- class ApiJob < ActiveJob::Base
184
- def perform(*)
185
- end
186
- end
187
- end
188
-
189
- class ApiWorker
190
- include Sidekiq::Worker
191
- end
192
-
193
- it 'can enumerate jobs' do
194
- q = Sidekiq::Queue.new
195
- Time.stub(:now, Time.new(2012, 12, 26)) do
196
- ApiWorker.perform_async(1, 'mike')
197
- assert_equal ['TestApi::ApiWorker'], q.map(&:klass)
198
-
199
- job = q.first
200
- assert_equal 24, job.jid.size
201
- assert_equal [1, 'mike'], job.args
202
- assert_equal Time.new(2012, 12, 26), job.enqueued_at
203
- end
204
- assert q.latency > 10_000_000
205
-
206
- q = Sidekiq::Queue.new('other')
207
- assert_equal 0, q.size
208
- end
209
-
210
- it 'has no enqueued_at time for jobs enqueued in the future' do
211
- job_id = ApiWorker.perform_in(100, 1, 'foo')
212
- job = Sidekiq::ScheduledSet.new.find_job(job_id)
213
- assert_nil job.enqueued_at
214
- end
215
-
216
- it 'unwraps delayed jobs' do
217
- Sidekiq::Queue.delay.foo(1,2,3)
218
- q = Sidekiq::Queue.new
219
- x = q.first
220
- assert_equal "Sidekiq::Queue.foo", x.display_class
221
- assert_equal [1,2,3], x.display_args
222
- end
223
-
224
- it 'unwraps ActiveJob jobs' do
225
- ApiJob.perform_later(1, 2, 3)
226
- q = Sidekiq::Queue.new
227
- x = q.first
228
- assert_equal "TestApi::ApiJob", x.display_class
229
- assert_equal [1,2,3], x.display_args
230
- end
231
-
232
- it 'unwraps ActionMailer jobs' do
233
- ApiMailer.test_email(1, 2, 3).deliver_later
234
- q = Sidekiq::Queue.new('mailers')
235
- x = q.first
236
- assert_equal "TestApi::ApiMailer#test_email", x.display_class
237
- assert_equal [1,2,3], x.display_args
238
- end
239
-
240
- it 'has no enqueued_at time for jobs enqueued in the future' do
241
- job_id = ApiWorker.perform_in(100, 1, 'foo')
242
- job = Sidekiq::ScheduledSet.new.find_job(job_id)
243
- assert_nil job.enqueued_at
244
- end
245
-
246
- it 'can delete jobs' do
247
- q = Sidekiq::Queue.new
248
- ApiWorker.perform_async(1, 'mike')
249
- assert_equal 1, q.size
250
-
251
- x = q.first
252
- assert_equal "TestApi::ApiWorker", x.display_class
253
- assert_equal [1,'mike'], x.display_args
254
-
255
- assert_equal [true], q.map(&:delete)
256
- assert_equal 0, q.size
257
- end
258
-
259
- it "can move scheduled job to queue" do
260
- remain_id = ApiWorker.perform_in(100, 1, 'jason')
261
- job_id = ApiWorker.perform_in(100, 1, 'jason')
262
- job = Sidekiq::ScheduledSet.new.find_job(job_id)
263
- q = Sidekiq::Queue.new
264
- job.add_to_queue
265
- queued_job = q.find_job(job_id)
266
- refute_nil queued_job
267
- assert_equal queued_job.jid, job_id
268
- assert_nil Sidekiq::ScheduledSet.new.find_job(job_id)
269
- refute_nil Sidekiq::ScheduledSet.new.find_job(remain_id)
270
- end
271
-
272
- it "handles multiple scheduled jobs when moving to queue" do
273
- jids = Sidekiq::Client.push_bulk('class' => ApiWorker,
274
- 'args' => [[1, 'jason'], [2, 'jason']],
275
- 'at' => Time.now.to_f)
276
- assert_equal 2, jids.size
277
- (remain_id, job_id) = jids
278
- job = Sidekiq::ScheduledSet.new.find_job(job_id)
279
- q = Sidekiq::Queue.new
280
- job.add_to_queue
281
- queued_job = q.find_job(job_id)
282
- refute_nil queued_job
283
- assert_equal queued_job.jid, job_id
284
- assert_nil Sidekiq::ScheduledSet.new.find_job(job_id)
285
- refute_nil Sidekiq::ScheduledSet.new.find_job(remain_id)
286
- end
287
-
288
- it 'can find job by id in sorted sets' do
289
- job_id = ApiWorker.perform_in(100, 1, 'jason')
290
- job = Sidekiq::ScheduledSet.new.find_job(job_id)
291
- refute_nil job
292
- assert_equal job_id, job.jid
293
- assert_in_delta job.latency, 0.0, 0.1
294
- end
295
-
296
- it 'can remove jobs when iterating over a sorted set' do
297
- # scheduled jobs must be greater than SortedSet#each underlying page size
298
- 51.times do
299
- ApiWorker.perform_in(100, 'aaron')
300
- end
301
- set = Sidekiq::ScheduledSet.new
302
- set.map(&:delete)
303
- assert_equal set.size, 0
304
- end
305
-
306
- it 'can remove jobs when iterating over a queue' do
307
- # initial queue size must be greater than Queue#each underlying page size
308
- 51.times do
309
- ApiWorker.perform_async(1, 'aaron')
310
- end
311
- q = Sidekiq::Queue.new
312
- q.map(&:delete)
313
- assert_equal q.size, 0
314
- end
315
-
316
- it 'can find job by id in queues' do
317
- q = Sidekiq::Queue.new
318
- job_id = ApiWorker.perform_async(1, 'jason')
319
- job = q.find_job(job_id)
320
- refute_nil job
321
- assert_equal job_id, job.jid
322
- end
323
-
324
- it 'can clear a queue' do
325
- q = Sidekiq::Queue.new
326
- 2.times { ApiWorker.perform_async(1, 'mike') }
327
- q.clear
328
-
329
- Sidekiq.redis do |conn|
330
- refute conn.smembers('queues').include?('foo')
331
- refute conn.exists('queue:foo')
332
- end
333
- end
334
-
335
- it 'can fetch by score' do
336
- same_time = Time.now.to_f
337
- add_retry('bob1', same_time)
338
- add_retry('bob2', same_time)
339
- r = Sidekiq::RetrySet.new
340
- assert_equal 2, r.fetch(same_time).size
341
- end
342
-
343
- it 'can fetch by score and jid' do
344
- same_time = Time.now.to_f
345
- add_retry('bob1', same_time)
346
- add_retry('bob2', same_time)
347
- r = Sidekiq::RetrySet.new
348
- assert_equal 1, r.fetch(same_time, 'bob1').size
349
- end
350
-
351
- it 'shows empty retries' do
352
- r = Sidekiq::RetrySet.new
353
- assert_equal 0, r.size
354
- end
355
-
356
- it 'can enumerate retries' do
357
- add_retry
358
-
359
- r = Sidekiq::RetrySet.new
360
- assert_equal 1, r.size
361
- array = r.to_a
362
- assert_equal 1, array.size
363
-
364
- retri = array.first
365
- assert_equal 'ApiWorker', retri.klass
366
- assert_equal 'default', retri.queue
367
- assert_equal 'bob', retri.jid
368
- assert_in_delta Time.now.to_f, retri.at.to_f, 0.02
369
- end
370
-
371
- it 'requires a jid to delete an entry' do
372
- start_time = Time.now.to_f
373
- add_retry('bob2', Time.now.to_f)
374
- assert_raises(ArgumentError) do
375
- Sidekiq::RetrySet.new.delete(start_time)
376
- end
377
- end
378
-
379
- it 'can delete a single retry from score and jid' do
380
- same_time = Time.now.to_f
381
- add_retry('bob1', same_time)
382
- add_retry('bob2', same_time)
383
- r = Sidekiq::RetrySet.new
384
- assert_equal 2, r.size
385
- Sidekiq::RetrySet.new.delete(same_time, 'bob1')
386
- assert_equal 1, r.size
387
- end
388
-
389
- it 'can retry a retry' do
390
- add_retry
391
- r = Sidekiq::RetrySet.new
392
- assert_equal 1, r.size
393
- r.first.retry
394
- assert_equal 0, r.size
395
- assert_equal 1, Sidekiq::Queue.new('default').size
396
- job = Sidekiq::Queue.new('default').first
397
- assert_equal 'bob', job.jid
398
- assert_equal 1, job['retry_count']
399
- end
400
-
401
- it 'can clear retries' do
402
- add_retry
403
- add_retry('test')
404
- r = Sidekiq::RetrySet.new
405
- assert_equal 2, r.size
406
- r.clear
407
- assert_equal 0, r.size
408
- end
409
-
410
- it 'can enumerate processes' do
411
- identity_string = "identity_string"
412
- odata = {
413
- 'pid' => 123,
414
- 'hostname' => Socket.gethostname,
415
- 'key' => identity_string,
416
- 'identity' => identity_string,
417
- 'started_at' => Time.now.to_f - 15,
418
- }
419
-
420
- time = Time.now.to_f
421
- Sidekiq.redis do |conn|
422
- conn.multi do
423
- conn.sadd('processes', odata['key'])
424
- conn.hmset(odata['key'], 'info', Sidekiq.dump_json(odata), 'busy', 10, 'beat', time)
425
- conn.sadd('processes', 'fake:pid')
426
- end
427
- end
428
-
429
- ps = Sidekiq::ProcessSet.new.to_a
430
- assert_equal 1, ps.size
431
- data = ps.first
432
- assert_equal 10, data['busy']
433
- assert_equal time, data['beat']
434
- assert_equal 123, data['pid']
435
- data.quiet!
436
- data.stop!
437
- signals_string = "#{odata['key']}-signals"
438
- assert_equal "TERM", Sidekiq.redis{|c| c.lpop(signals_string) }
439
- assert_equal "USR1", Sidekiq.redis{|c| c.lpop(signals_string) }
440
- end
441
-
442
- it 'can enumerate workers' do
443
- w = Sidekiq::Workers.new
444
- assert_equal 0, w.size
445
- w.each do
446
- assert false
447
- end
448
-
449
- hn = Socket.gethostname
450
- key = "#{hn}:#{$$}"
451
- pdata = { 'pid' => $$, 'hostname' => hn, 'started_at' => Time.now.to_i }
452
- Sidekiq.redis do |conn|
453
- conn.sadd('processes', key)
454
- conn.hmset(key, 'info', Sidekiq.dump_json(pdata), 'busy', 0, 'beat', Time.now.to_f)
455
- end
456
-
457
- s = "#{key}:workers"
458
- data = Sidekiq.dump_json({ 'payload' => {}, 'queue' => 'default', 'run_at' => Time.now.to_i })
459
- Sidekiq.redis do |c|
460
- c.hmset(s, '1234', data)
461
- end
462
-
463
- w.each do |p, x, y|
464
- assert_equal key, p
465
- assert_equal "1234", x
466
- assert_equal 'default', y['queue']
467
- assert_equal Time.now.year, Time.at(y['run_at']).year
468
- end
469
-
470
- s = "#{key}:workers"
471
- data = Sidekiq.dump_json({ 'payload' => {}, 'queue' => 'default', 'run_at' => (Time.now.to_i - 2*60*60) })
472
- Sidekiq.redis do |c|
473
- c.multi do
474
- c.hmset(s, '5678', data)
475
- c.hmset("b#{s}", '5678', data)
476
- end
477
- end
478
-
479
- assert_equal ['1234', '5678'], w.map { |_, tid, _| tid }
480
- end
481
-
482
- it 'can reschedule jobs' do
483
- add_retry('foo1')
484
- add_retry('foo2')
485
-
486
- retries = Sidekiq::RetrySet.new
487
- assert_equal 2, retries.size
488
- refute(retries.map { |r| r.score > (Time.now.to_f + 9) }.any?)
489
-
490
- retries.each do |retri|
491
- retri.reschedule(Time.now.to_f + 10) if retri.jid == 'foo2'
492
- end
493
-
494
- assert_equal 2, retries.size
495
- assert(retries.map { |r| r.score > (Time.now.to_f + 9) }.any?)
496
- end
497
-
498
- it 'prunes processes which have died' do
499
- data = { 'pid' => rand(10_000), 'hostname' => "app#{rand(1_000)}", 'started_at' => Time.now.to_f }
500
- key = "#{data['hostname']}:#{data['pid']}"
501
- Sidekiq.redis do |conn|
502
- conn.sadd('processes', key)
503
- conn.hmset(key, 'info', Sidekiq.dump_json(data), 'busy', 0, 'beat', Time.now.to_f)
504
- end
505
-
506
- ps = Sidekiq::ProcessSet.new
507
- assert_equal 1, ps.size
508
- assert_equal 1, ps.to_a.size
509
-
510
- Sidekiq.redis do |conn|
511
- conn.sadd('processes', "bar:987")
512
- conn.sadd('processes', "bar:986")
513
- end
514
-
515
- ps = Sidekiq::ProcessSet.new
516
- assert_equal 1, ps.size
517
- assert_equal 1, ps.to_a.size
518
- end
519
-
520
- def add_retry(jid = 'bob', at = Time.now.to_f)
521
- payload = Sidekiq.dump_json('class' => 'ApiWorker', 'args' => [1, 'mike'], 'queue' => 'default', 'jid' => jid, 'retry_count' => 2, 'failed_at' => Time.now.to_f)
522
- Sidekiq.redis do |conn|
523
- conn.zadd('retry', at.to_s, payload)
524
- end
525
- end
526
- end
527
- end
528
- end