sidekiq 4.2.4 → 5.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.
- checksums.yaml +4 -4
- data/.github/issue_template.md +8 -1
- data/.gitignore +1 -0
- data/.travis.yml +5 -3
- data/5.0-Upgrade.md +56 -0
- data/COMM-LICENSE +1 -1
- data/Changes.md +151 -0
- data/Ent-Changes.md +77 -2
- data/Gemfile +10 -25
- data/LICENSE +1 -1
- data/Pro-4.0-Upgrade.md +35 -0
- data/Pro-Changes.md +156 -2
- data/README.md +9 -6
- data/Rakefile +1 -2
- data/bin/sidekiqctl +1 -1
- data/bin/sidekiqload +15 -33
- data/lib/generators/sidekiq/templates/worker_spec.rb.erb +1 -1
- data/lib/generators/sidekiq/templates/worker_test.rb.erb +1 -1
- data/lib/sidekiq/api.rb +157 -67
- data/lib/sidekiq/cli.rb +71 -26
- data/lib/sidekiq/client.rb +25 -18
- data/lib/sidekiq/core_ext.rb +1 -106
- data/lib/sidekiq/delay.rb +42 -0
- data/lib/sidekiq/exception_handler.rb +2 -4
- data/lib/sidekiq/extensions/generic_proxy.rb +7 -1
- data/lib/sidekiq/fetch.rb +1 -1
- data/lib/sidekiq/job_logger.rb +25 -0
- data/lib/sidekiq/job_retry.rb +241 -0
- data/lib/sidekiq/launcher.rb +45 -37
- data/lib/sidekiq/logging.rb +18 -2
- data/lib/sidekiq/manager.rb +3 -4
- data/lib/sidekiq/middleware/server/active_record.rb +10 -0
- data/lib/sidekiq/processor.rb +91 -34
- data/lib/sidekiq/rails.rb +15 -51
- data/lib/sidekiq/redis_connection.rb +31 -5
- data/lib/sidekiq/scheduled.rb +35 -8
- data/lib/sidekiq/testing.rb +24 -7
- data/lib/sidekiq/util.rb +6 -2
- data/lib/sidekiq/version.rb +1 -1
- data/lib/sidekiq/web/action.rb +2 -6
- data/lib/sidekiq/web/application.rb +28 -21
- data/lib/sidekiq/web/helpers.rb +67 -23
- data/lib/sidekiq/web/router.rb +14 -10
- data/lib/sidekiq/web.rb +4 -4
- data/lib/sidekiq/worker.rb +97 -14
- data/lib/sidekiq.rb +23 -24
- data/sidekiq.gemspec +7 -10
- data/web/assets/javascripts/application.js +0 -0
- data/web/assets/javascripts/dashboard.js +18 -13
- data/web/assets/stylesheets/application-rtl.css +246 -0
- data/web/assets/stylesheets/application.css +336 -4
- data/web/assets/stylesheets/bootstrap-rtl.min.css +9 -0
- data/web/assets/stylesheets/bootstrap.css +2 -2
- data/web/locales/ar.yml +80 -0
- data/web/locales/en.yml +1 -0
- data/web/locales/es.yml +4 -3
- data/web/locales/fa.yml +80 -0
- data/web/locales/he.yml +79 -0
- data/web/locales/ja.yml +5 -3
- data/web/locales/ur.yml +80 -0
- data/web/views/_footer.erb +5 -2
- data/web/views/_job_info.erb +1 -1
- data/web/views/_nav.erb +1 -1
- data/web/views/_paging.erb +1 -1
- data/web/views/busy.erb +9 -5
- data/web/views/dashboard.erb +3 -3
- data/web/views/layout.erb +11 -2
- data/web/views/morgue.erb +14 -10
- data/web/views/queue.erb +10 -10
- data/web/views/queues.erb +4 -2
- data/web/views/retries.erb +13 -11
- data/web/views/retry.erb +1 -1
- data/web/views/scheduled.erb +2 -2
- metadata +26 -160
- data/lib/sidekiq/middleware/server/logging.rb +0 -40
- data/lib/sidekiq/middleware/server/retry_jobs.rb +0 -205
- data/test/config.yml +0 -9
- data/test/env_based_config.yml +0 -11
- data/test/fake_env.rb +0 -1
- data/test/fixtures/en.yml +0 -2
- data/test/helper.rb +0 -75
- data/test/test_actors.rb +0 -138
- data/test/test_api.rb +0 -528
- data/test/test_cli.rb +0 -418
- data/test/test_client.rb +0 -266
- data/test/test_exception_handler.rb +0 -56
- data/test/test_extensions.rb +0 -127
- data/test/test_fetch.rb +0 -50
- data/test/test_launcher.rb +0 -95
- data/test/test_logging.rb +0 -35
- data/test/test_manager.rb +0 -50
- data/test/test_middleware.rb +0 -158
- data/test/test_processor.rb +0 -235
- data/test/test_rails.rb +0 -22
- data/test/test_redis_connection.rb +0 -132
- data/test/test_retry.rb +0 -326
- data/test/test_retry_exhausted.rb +0 -149
- data/test/test_scheduled.rb +0 -115
- data/test/test_scheduling.rb +0 -58
- data/test/test_sidekiq.rb +0 -107
- data/test/test_testing.rb +0 -143
- data/test/test_testing_fake.rb +0 -357
- data/test/test_testing_inline.rb +0 -94
- data/test/test_util.rb +0 -13
- data/test/test_web.rb +0 -726
- 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
|