sidekiq 3.4.1 → 4.0.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of sidekiq might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/4.0-Upgrade.md +50 -0
- data/COMM-LICENSE +55 -45
- data/Changes.md +73 -1
- data/Ent-Changes.md +66 -0
- data/Gemfile +7 -1
- data/Pro-2.0-Upgrade.md +2 -2
- data/Pro-3.0-Upgrade.md +46 -0
- data/Pro-Changes.md +65 -2
- data/README.md +8 -9
- data/bin/sidekiq +5 -0
- data/bin/sidekiqctl +8 -2
- data/bin/sidekiqload +167 -0
- data/lib/sidekiq/api.rb +29 -31
- data/lib/sidekiq/cli.rb +41 -42
- data/lib/sidekiq/client.rb +5 -10
- data/lib/sidekiq/fetch.rb +35 -111
- data/lib/sidekiq/launcher.rb +102 -42
- data/lib/sidekiq/manager.rb +78 -180
- data/lib/sidekiq/middleware/server/logging.rb +10 -5
- data/lib/sidekiq/middleware/server/retry_jobs.rb +5 -5
- data/lib/sidekiq/processor.rb +126 -97
- data/lib/sidekiq/redis_connection.rb +23 -5
- data/lib/sidekiq/scheduled.rb +47 -26
- data/lib/sidekiq/testing.rb +96 -17
- data/lib/sidekiq/util.rb +20 -0
- data/lib/sidekiq/version.rb +1 -1
- data/lib/sidekiq/web.rb +17 -1
- data/lib/sidekiq/web_helpers.rb +26 -4
- data/lib/sidekiq/worker.rb +14 -0
- data/lib/sidekiq.rb +37 -14
- data/sidekiq.gemspec +11 -11
- data/test/helper.rb +45 -10
- data/test/test_actors.rb +137 -0
- data/test/test_api.rb +388 -388
- data/test/test_cli.rb +29 -59
- data/test/test_client.rb +60 -135
- data/test/test_extensions.rb +29 -23
- data/test/test_fetch.rb +2 -57
- data/test/test_launcher.rb +80 -0
- data/test/test_logging.rb +1 -1
- data/test/test_manager.rb +16 -131
- data/test/test_middleware.rb +3 -5
- data/test/test_processor.rb +110 -76
- data/test/test_rails.rb +21 -0
- data/test/test_redis_connection.rb +0 -1
- data/test/test_retry.rb +114 -162
- data/test/test_scheduled.rb +11 -17
- data/test/test_scheduling.rb +20 -42
- data/test/test_sidekiq.rb +46 -16
- data/test/test_testing.rb +80 -20
- data/test/test_testing_fake.rb +68 -8
- data/test/test_testing_inline.rb +3 -3
- data/test/test_util.rb +16 -0
- data/test/test_web.rb +17 -3
- data/test/test_web_helpers.rb +3 -2
- data/web/assets/images/favicon.ico +0 -0
- data/web/assets/javascripts/application.js +6 -1
- data/web/assets/javascripts/dashboard.js +2 -8
- data/web/assets/javascripts/locales/jquery.timeago.pt-br.js +14 -14
- data/web/assets/stylesheets/application.css +33 -56
- data/web/locales/de.yml +1 -1
- data/web/locales/en.yml +1 -0
- data/web/locales/{no.yml → nb.yml} +10 -2
- data/web/locales/uk.yml +76 -0
- data/web/views/_footer.erb +2 -7
- data/web/views/_job_info.erb +1 -1
- data/web/views/_nav.erb +2 -2
- data/web/views/_poll_js.erb +5 -0
- data/web/views/{_poll.erb → _poll_link.erb} +0 -3
- data/web/views/busy.erb +2 -1
- data/web/views/dead.erb +1 -0
- data/web/views/layout.erb +2 -0
- data/web/views/morgue.erb +3 -0
- data/web/views/queue.erb +1 -0
- data/web/views/queues.erb +1 -0
- data/web/views/retries.erb +3 -0
- data/web/views/retry.erb +1 -0
- data/web/views/scheduled.erb +1 -0
- data/web/views/scheduled_job_info.erb +1 -0
- metadata +81 -47
- data/lib/sidekiq/actor.rb +0 -39
- data/test/test_worker_generator.rb +0 -17
data/test/test_cli.rb
CHANGED
@@ -128,7 +128,7 @@ class TestCli < Sidekiq::Test
|
|
128
128
|
|
129
129
|
it 'appends messages to a logfile' do
|
130
130
|
File.open(@tmp_log_path, 'w') do |f|
|
131
|
-
f.puts 'already
|
131
|
+
f.puts 'already existent log message'
|
132
132
|
end
|
133
133
|
|
134
134
|
@cli.parse(['sidekiq', '-L', @tmp_log_path, '-r', './test/fake_env.rb'])
|
@@ -136,7 +136,7 @@ class TestCli < Sidekiq::Test
|
|
136
136
|
Sidekiq.logger.info('test message')
|
137
137
|
|
138
138
|
log_file_content = File.read(@tmp_log_path)
|
139
|
-
assert_match(/already
|
139
|
+
assert_match(/already existent/, log_file_content, "didn't include the old message")
|
140
140
|
assert_match(/test message/, log_file_content, "didn't include the new message")
|
141
141
|
end
|
142
142
|
end
|
@@ -168,35 +168,14 @@ class TestCli < Sidekiq::Test
|
|
168
168
|
@cli.parse(['sidekiq', '-C', './test/config.yml'])
|
169
169
|
end
|
170
170
|
|
171
|
-
it '
|
171
|
+
it 'parses as expected' do
|
172
172
|
assert_equal './test/config.yml', Sidekiq.options[:config_file]
|
173
|
-
end
|
174
|
-
|
175
|
-
it 'sets verbose' do
|
176
173
|
refute Sidekiq.options[:verbose]
|
177
|
-
end
|
178
|
-
|
179
|
-
it 'sets require file' do
|
180
174
|
assert_equal './test/fake_env.rb', Sidekiq.options[:require]
|
181
|
-
end
|
182
|
-
|
183
|
-
it 'does not set environment' do
|
184
175
|
assert_equal nil, Sidekiq.options[:environment]
|
185
|
-
end
|
186
|
-
|
187
|
-
it 'sets concurrency' do
|
188
176
|
assert_equal 50, Sidekiq.options[:concurrency]
|
189
|
-
end
|
190
|
-
|
191
|
-
it 'sets pid file' do
|
192
177
|
assert_equal '/tmp/sidekiq-config-test.pid', Sidekiq.options[:pidfile]
|
193
|
-
end
|
194
|
-
|
195
|
-
it 'sets logfile' do
|
196
178
|
assert_equal '/tmp/sidekiq.log', Sidekiq.options[:logfile]
|
197
|
-
end
|
198
|
-
|
199
|
-
it 'sets queues' do
|
200
179
|
assert_equal 2, Sidekiq.options[:queues].count { |q| q == 'very_often' }
|
201
180
|
assert_equal 1, Sidekiq.options[:queues].count { |q| q == 'seldom' }
|
202
181
|
end
|
@@ -207,35 +186,14 @@ class TestCli < Sidekiq::Test
|
|
207
186
|
@cli.parse(['sidekiq', '-e', 'staging', '-C', './test/env_based_config.yml'])
|
208
187
|
end
|
209
188
|
|
210
|
-
it '
|
189
|
+
it 'parses as expected' do
|
211
190
|
assert_equal './test/env_based_config.yml', Sidekiq.options[:config_file]
|
212
|
-
end
|
213
|
-
|
214
|
-
it 'sets verbose' do
|
215
191
|
refute Sidekiq.options[:verbose]
|
216
|
-
end
|
217
|
-
|
218
|
-
it 'sets require file' do
|
219
192
|
assert_equal './test/fake_env.rb', Sidekiq.options[:require]
|
220
|
-
end
|
221
|
-
|
222
|
-
it 'sets environment' do
|
223
193
|
assert_equal 'staging', Sidekiq.options[:environment]
|
224
|
-
end
|
225
|
-
|
226
|
-
it 'sets concurrency' do
|
227
194
|
assert_equal 5, Sidekiq.options[:concurrency]
|
228
|
-
end
|
229
|
-
|
230
|
-
it 'sets pid file' do
|
231
195
|
assert_equal '/tmp/sidekiq-config-test.pid', Sidekiq.options[:pidfile]
|
232
|
-
end
|
233
|
-
|
234
|
-
it 'sets logfile' do
|
235
196
|
assert_equal '/tmp/sidekiq.log', Sidekiq.options[:logfile]
|
236
|
-
end
|
237
|
-
|
238
|
-
it 'sets queues' do
|
239
197
|
assert_equal 2, Sidekiq.options[:queues].count { |q| q == 'very_often' }
|
240
198
|
assert_equal 1, Sidekiq.options[:queues].count { |q| q == 'seldom' }
|
241
199
|
end
|
@@ -297,23 +255,11 @@ class TestCli < Sidekiq::Test
|
|
297
255
|
File.unlink @tmp_path if File.exist? @tmp_path
|
298
256
|
end
|
299
257
|
|
300
|
-
it '
|
258
|
+
it 'gives the expected options' do
|
301
259
|
assert_equal 100, Sidekiq.options[:concurrency]
|
302
|
-
end
|
303
|
-
|
304
|
-
it 'uses require file flag' do
|
305
260
|
assert_equal @tmp_lib_path, Sidekiq.options[:require]
|
306
|
-
end
|
307
|
-
|
308
|
-
it 'uses environment flag' do
|
309
261
|
assert_equal 'snoop', Sidekiq.options[:environment]
|
310
|
-
end
|
311
|
-
|
312
|
-
it 'uses pidfile flag' do
|
313
262
|
assert_equal @tmp_path, Sidekiq.options[:pidfile]
|
314
|
-
end
|
315
|
-
|
316
|
-
it 'sets queues' do
|
317
263
|
assert_equal 7, Sidekiq.options[:queues].count { |q| q == 'often' }
|
318
264
|
assert_equal 3, Sidekiq.options[:queues].count { |q| q == 'seldom' }
|
319
265
|
end
|
@@ -362,4 +308,28 @@ class TestCli < Sidekiq::Test
|
|
362
308
|
end
|
363
309
|
end
|
364
310
|
|
311
|
+
describe 'misc' do
|
312
|
+
it 'handles interrupts' do
|
313
|
+
cli = Sidekiq::CLI.new
|
314
|
+
assert_raises Interrupt do
|
315
|
+
cli.handle_signal('INT')
|
316
|
+
end
|
317
|
+
assert_raises Interrupt do
|
318
|
+
cli.handle_signal('TERM')
|
319
|
+
end
|
320
|
+
cli.handle_signal('USR2')
|
321
|
+
cli.handle_signal('TTIN')
|
322
|
+
end
|
323
|
+
|
324
|
+
it 'can fire events' do
|
325
|
+
count = 0
|
326
|
+
Sidekiq.options[:lifecycle_events][:startup] = [proc {
|
327
|
+
count += 1
|
328
|
+
}]
|
329
|
+
cli = Sidekiq::CLI.new
|
330
|
+
cli.fire_event(:startup)
|
331
|
+
assert_equal 1, count
|
332
|
+
end
|
333
|
+
end
|
334
|
+
|
365
335
|
end
|
data/test/test_client.rb
CHANGED
@@ -1,33 +1,7 @@
|
|
1
1
|
require_relative 'helper'
|
2
|
-
require 'sidekiq/client'
|
3
|
-
require 'sidekiq/worker'
|
4
2
|
|
5
3
|
class TestClient < Sidekiq::Test
|
6
|
-
describe '
|
7
|
-
before do
|
8
|
-
@redis = Minitest::Mock.new
|
9
|
-
def @redis.multi; [yield] * 2 if block_given?; end
|
10
|
-
def @redis.set(*); true; end
|
11
|
-
def @redis.sadd(*); true; end
|
12
|
-
def @redis.srem(*); true; end
|
13
|
-
def @redis.get(*); nil; end
|
14
|
-
def @redis.del(*); nil; end
|
15
|
-
def @redis.incrby(*); nil; end
|
16
|
-
def @redis.setex(*); true; end
|
17
|
-
def @redis.expire(*); true; end
|
18
|
-
def @redis.watch(*); true; end
|
19
|
-
def @redis.with_connection; yield self; end
|
20
|
-
def @redis.with; yield self; end
|
21
|
-
def @redis.exec; true; end
|
22
|
-
Sidekiq.instance_variable_set(:@redis, @redis)
|
23
|
-
Sidekiq::Client.instance_variable_set(:@default, nil)
|
24
|
-
end
|
25
|
-
|
26
|
-
after do
|
27
|
-
Sidekiq.redis = REDIS
|
28
|
-
Sidekiq::Client.instance_variable_set(:@default, nil)
|
29
|
-
end
|
30
|
-
|
4
|
+
describe 'errors' do
|
31
5
|
it 'raises ArgumentError with invalid params' do
|
32
6
|
assert_raises ArgumentError do
|
33
7
|
Sidekiq::Client.push('foo', 1)
|
@@ -49,112 +23,71 @@ class TestClient < Sidekiq::Test
|
|
49
23
|
Sidekiq::Client.push('queue' => 'foo', 'class' => MyWorker, 'args' => 1)
|
50
24
|
end
|
51
25
|
end
|
26
|
+
end
|
52
27
|
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
end
|
60
|
-
|
61
|
-
it 'allows local middleware modification' do
|
62
|
-
@redis.expect :lpush, 1, ['queue:default', Array]
|
63
|
-
$called = false
|
64
|
-
mware = Class.new { def call(worker_klass,msg,q,r); $called = true; msg;end }
|
65
|
-
client = Sidekiq::Client.new
|
66
|
-
client.middleware do |chain|
|
67
|
-
chain.add mware
|
68
|
-
end
|
69
|
-
client.push('class' => 'Blah', 'args' => [1,2,3])
|
28
|
+
describe 'as instance' do
|
29
|
+
it 'can push' do
|
30
|
+
client = Sidekiq::Client.new
|
31
|
+
jid = client.push('class' => 'Blah', 'args' => [1,2,3])
|
32
|
+
assert_equal 24, jid.size
|
33
|
+
end
|
70
34
|
|
71
|
-
|
72
|
-
|
73
|
-
|
35
|
+
it 'allows local middleware modification' do
|
36
|
+
$called = false
|
37
|
+
mware = Class.new { def call(worker_klass,msg,q,r); $called = true; msg;end }
|
38
|
+
client = Sidekiq::Client.new
|
39
|
+
client.middleware do |chain|
|
40
|
+
chain.add mware
|
74
41
|
end
|
42
|
+
client.push('class' => 'Blah', 'args' => [1,2,3])
|
43
|
+
|
44
|
+
assert $called
|
45
|
+
assert client.middleware.exists?(mware)
|
46
|
+
refute Sidekiq.client_middleware.exists?(mware)
|
75
47
|
end
|
48
|
+
end
|
76
49
|
|
50
|
+
describe 'client' do
|
77
51
|
it 'pushes messages to redis' do
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
52
|
+
q = Sidekiq::Queue.new('foo')
|
53
|
+
pre = q.size
|
54
|
+
jid = Sidekiq::Client.push('queue' => 'foo', 'class' => MyWorker, 'args' => [1, 2])
|
55
|
+
assert jid
|
56
|
+
assert_equal 24, jid.size
|
57
|
+
assert_equal pre + 1, q.size
|
83
58
|
end
|
84
59
|
|
85
60
|
it 'pushes messages to redis using a String class' do
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
61
|
+
q = Sidekiq::Queue.new('foo')
|
62
|
+
pre = q.size
|
63
|
+
jid = Sidekiq::Client.push('queue' => 'foo', 'class' => 'MyWorker', 'args' => [1, 2])
|
64
|
+
assert jid
|
65
|
+
assert_equal 24, jid.size
|
66
|
+
assert_equal pre + 1, q.size
|
91
67
|
end
|
92
68
|
|
93
69
|
class MyWorker
|
94
70
|
include Sidekiq::Worker
|
95
71
|
end
|
96
72
|
|
97
|
-
it 'has default options' do
|
98
|
-
assert_equal Sidekiq.default_worker_options, MyWorker.get_sidekiq_options
|
99
|
-
end
|
100
|
-
|
101
|
-
it 'handles perform_async' do
|
102
|
-
@redis.expect :lpush, 1, ['queue:default', Array]
|
103
|
-
pushed = MyWorker.perform_async(1, 2)
|
104
|
-
assert pushed
|
105
|
-
@redis.verify
|
106
|
-
end
|
107
|
-
|
108
|
-
it 'enqueues messages to redis' do
|
109
|
-
@redis.expect :lpush, 1, ['queue:default', Array]
|
110
|
-
pushed = Sidekiq::Client.enqueue(MyWorker, 1, 2)
|
111
|
-
assert pushed
|
112
|
-
@redis.verify
|
113
|
-
end
|
114
|
-
|
115
|
-
it 'enqueues messages to redis' do
|
116
|
-
@redis.expect :lpush, 1, ['queue:custom_queue', Array]
|
117
|
-
pushed = Sidekiq::Client.enqueue_to(:custom_queue, MyWorker, 1, 2)
|
118
|
-
assert pushed
|
119
|
-
@redis.verify
|
120
|
-
end
|
121
|
-
|
122
|
-
it 'enqueues messages to redis (delayed, custom queue)' do
|
123
|
-
@redis.expect :zadd, 1, ['schedule', Array]
|
124
|
-
pushed = Sidekiq::Client.enqueue_to_in(:custom_queue, 3.minutes, MyWorker, 1, 2)
|
125
|
-
assert pushed
|
126
|
-
@redis.verify
|
127
|
-
end
|
128
|
-
|
129
|
-
it 'enqueues messages to redis (delayed into past, custom queue)' do
|
130
|
-
@redis.expect :lpush, 1, ['queue:custom_queue', Array]
|
131
|
-
pushed = Sidekiq::Client.enqueue_to_in(:custom_queue, -3.minutes, MyWorker, 1, 2)
|
132
|
-
assert pushed
|
133
|
-
@redis.verify
|
134
|
-
end
|
135
|
-
|
136
|
-
it 'enqueues messages to redis (delayed)' do
|
137
|
-
@redis.expect :zadd, 1, ['schedule', Array]
|
138
|
-
pushed = Sidekiq::Client.enqueue_in(3.minutes, MyWorker, 1, 2)
|
139
|
-
assert pushed
|
140
|
-
@redis.verify
|
141
|
-
end
|
142
|
-
|
143
73
|
class QueuedWorker
|
144
74
|
include Sidekiq::Worker
|
145
75
|
sidekiq_options :queue => :flimflam
|
146
76
|
end
|
147
77
|
|
148
|
-
it 'enqueues
|
149
|
-
|
150
|
-
|
151
|
-
assert
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
assert_equal
|
78
|
+
it 'enqueues' do
|
79
|
+
Sidekiq.redis {|c| c.flushdb }
|
80
|
+
assert_equal Sidekiq.default_worker_options, MyWorker.get_sidekiq_options
|
81
|
+
assert MyWorker.perform_async(1, 2)
|
82
|
+
assert Sidekiq::Client.enqueue(MyWorker, 1, 2)
|
83
|
+
assert Sidekiq::Client.enqueue_to(:custom_queue, MyWorker, 1, 2)
|
84
|
+
assert_equal 1, Sidekiq::Queue.new('custom_queue').size
|
85
|
+
assert Sidekiq::Client.enqueue_to_in(:custom_queue, 3.minutes, MyWorker, 1, 2)
|
86
|
+
assert Sidekiq::Client.enqueue_to_in(:custom_queue, -3.minutes, MyWorker, 1, 2)
|
87
|
+
assert_equal 2, Sidekiq::Queue.new('custom_queue').size
|
88
|
+
assert Sidekiq::Client.enqueue_in(3.minutes, MyWorker, 1, 2)
|
89
|
+
assert QueuedWorker.perform_async(1, 2)
|
90
|
+
assert_equal 1, Sidekiq::Queue.new('flimflam').size
|
158
91
|
end
|
159
92
|
end
|
160
93
|
|
@@ -191,24 +124,23 @@ class TestClient < Sidekiq::Test
|
|
191
124
|
end
|
192
125
|
|
193
126
|
describe 'client middleware' do
|
194
|
-
|
195
127
|
class Stopper
|
196
|
-
def call(worker_class,
|
128
|
+
def call(worker_class, job, queue, r)
|
197
129
|
raise ArgumentError unless r
|
198
|
-
yield if
|
130
|
+
yield if job['args'].first.odd?
|
199
131
|
end
|
200
132
|
end
|
201
133
|
|
202
134
|
it 'can stop some of the jobs from pushing' do
|
203
|
-
Sidekiq.
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
135
|
+
client = Sidekiq::Client.new
|
136
|
+
client.middleware do |chain|
|
137
|
+
chain.add Stopper
|
138
|
+
end
|
139
|
+
|
140
|
+
assert_equal nil, client.push('class' => MyWorker, 'args' => [0])
|
141
|
+
assert_match(/[0-9a-f]{12}/, client.push('class' => MyWorker, 'args' => [1]))
|
142
|
+
client.push_bulk('class' => MyWorker, 'args' => [[0], [1]]).each do |jid|
|
143
|
+
assert_match(/[0-9a-f]{12}/, jid)
|
212
144
|
end
|
213
145
|
end
|
214
146
|
end
|
@@ -220,19 +152,10 @@ class TestClient < Sidekiq::Test
|
|
220
152
|
end
|
221
153
|
end
|
222
154
|
|
223
|
-
describe 'item normalization' do
|
224
|
-
it 'defaults retry to true' do
|
225
|
-
assert_equal true, Sidekiq::Client.new.__send__(:normalize_item, 'class' => QueuedWorker, 'args' => [])['retry']
|
226
|
-
end
|
227
|
-
|
228
|
-
it "does not normalize numeric retry's" do
|
229
|
-
assert_equal 2, Sidekiq::Client.new.__send__(:normalize_item, 'class' => CWorker, 'args' => [])['retry']
|
230
|
-
end
|
231
|
-
end
|
232
|
-
|
233
155
|
describe 'sharding' do
|
234
156
|
class DWorker < BaseWorker
|
235
157
|
end
|
158
|
+
|
236
159
|
it 'allows sidekiq_options to point to different Redi' do
|
237
160
|
conn = MiniTest::Mock.new
|
238
161
|
conn.expect(:multi, [0, 1])
|
@@ -240,6 +163,7 @@ class TestClient < Sidekiq::Test
|
|
240
163
|
DWorker.perform_async(1,2,3)
|
241
164
|
conn.verify
|
242
165
|
end
|
166
|
+
|
243
167
|
it 'allows #via to point to different Redi' do
|
244
168
|
conn = MiniTest::Mock.new
|
245
169
|
conn.expect(:multi, [0, 1])
|
@@ -257,6 +181,7 @@ class TestClient < Sidekiq::Test
|
|
257
181
|
assert_equal default, Sidekiq::Client.new.redis_pool
|
258
182
|
conn.verify
|
259
183
|
end
|
184
|
+
|
260
185
|
it 'allows Resque helpers to point to different Redi' do
|
261
186
|
conn = MiniTest::Mock.new
|
262
187
|
conn.expect(:multi, []) { |*args, &block| block.call }
|
data/test/test_extensions.rb
CHANGED
@@ -23,30 +23,34 @@ class TestExtensions < Sidekiq::Test
|
|
23
23
|
|
24
24
|
it 'allows delayed execution of ActiveRecord class methods' do
|
25
25
|
assert_equal [], Sidekiq::Queue.all.map(&:name)
|
26
|
-
|
26
|
+
q = Sidekiq::Queue.new
|
27
|
+
assert_equal 0, q.size
|
27
28
|
MyModel.delay.long_class_method
|
28
29
|
assert_equal ['default'], Sidekiq::Queue.all.map(&:name)
|
29
|
-
assert_equal 1,
|
30
|
+
assert_equal 1, q.size
|
30
31
|
end
|
31
32
|
|
32
33
|
it 'uses and stringifies specified options' do
|
33
34
|
assert_equal [], Sidekiq::Queue.all.map(&:name)
|
34
|
-
|
35
|
+
q = Sidekiq::Queue.new('notdefault')
|
36
|
+
assert_equal 0, q.size
|
35
37
|
MyModel.delay(queue: :notdefault).long_class_method
|
36
38
|
assert_equal ['notdefault'], Sidekiq::Queue.all.map(&:name)
|
37
|
-
assert_equal 1,
|
39
|
+
assert_equal 1, q.size
|
38
40
|
end
|
39
41
|
|
40
42
|
it 'allows delayed scheduling of AR class methods' do
|
41
|
-
|
43
|
+
ss = Sidekiq::ScheduledSet.new
|
44
|
+
assert_equal 0, ss.size
|
42
45
|
MyModel.delay_for(5.days).long_class_method
|
43
|
-
assert_equal 1,
|
46
|
+
assert_equal 1, ss.size
|
44
47
|
end
|
45
48
|
|
46
49
|
it 'allows until delayed scheduling of AR class methods' do
|
47
|
-
|
50
|
+
ss = Sidekiq::ScheduledSet.new
|
51
|
+
assert_equal 0, ss.size
|
48
52
|
MyModel.delay_until(1.day.from_now).long_class_method
|
49
|
-
assert_equal 1,
|
53
|
+
assert_equal 1, ss.size
|
50
54
|
end
|
51
55
|
|
52
56
|
class UserMailer < ActionMailer::Base
|
@@ -57,22 +61,25 @@ class TestExtensions < Sidekiq::Test
|
|
57
61
|
|
58
62
|
it 'allows delayed delivery of ActionMailer mails' do
|
59
63
|
assert_equal [], Sidekiq::Queue.all.map(&:name)
|
60
|
-
|
64
|
+
q = Sidekiq::Queue.new
|
65
|
+
assert_equal 0, q.size
|
61
66
|
UserMailer.delay.greetings(1, 2)
|
62
67
|
assert_equal ['default'], Sidekiq::Queue.all.map(&:name)
|
63
|
-
assert_equal 1,
|
68
|
+
assert_equal 1, q.size
|
64
69
|
end
|
65
70
|
|
66
71
|
it 'allows delayed scheduling of AM mails' do
|
67
|
-
|
72
|
+
ss = Sidekiq::ScheduledSet.new
|
73
|
+
assert_equal 0, ss.size
|
68
74
|
UserMailer.delay_for(5.days).greetings(1, 2)
|
69
|
-
assert_equal 1,
|
75
|
+
assert_equal 1, ss.size
|
70
76
|
end
|
71
77
|
|
72
78
|
it 'allows until delay scheduling of AM mails' do
|
73
|
-
|
79
|
+
ss = Sidekiq::ScheduledSet.new
|
80
|
+
assert_equal 0, ss.size
|
74
81
|
UserMailer.delay_until(5.days.from_now).greetings(1, 2)
|
75
|
-
assert_equal 1,
|
82
|
+
assert_equal 1, ss.size
|
76
83
|
end
|
77
84
|
|
78
85
|
class SomeClass
|
@@ -81,9 +88,10 @@ class TestExtensions < Sidekiq::Test
|
|
81
88
|
end
|
82
89
|
|
83
90
|
it 'allows delay of any ole class method' do
|
84
|
-
|
91
|
+
q = Sidekiq::Queue.new
|
92
|
+
assert_equal 0, q.size
|
85
93
|
SomeClass.delay.doit(Date.today)
|
86
|
-
assert_equal 1,
|
94
|
+
assert_equal 1, q.size
|
87
95
|
end
|
88
96
|
|
89
97
|
module SomeModule
|
@@ -92,18 +100,16 @@ class TestExtensions < Sidekiq::Test
|
|
92
100
|
end
|
93
101
|
|
94
102
|
it 'allows delay of any module class method' do
|
95
|
-
|
103
|
+
q = Sidekiq::Queue.new
|
104
|
+
assert_equal 0, q.size
|
96
105
|
SomeModule.delay.doit(Date.today)
|
97
|
-
assert_equal 1,
|
98
|
-
end
|
99
|
-
|
100
|
-
def queue_size(name='default')
|
101
|
-
Sidekiq::Queue.new(name).size
|
106
|
+
assert_equal 1, q.size
|
102
107
|
end
|
103
108
|
|
104
109
|
it 'allows removing of the #delay methods' do
|
110
|
+
q = Sidekiq::Queue.new
|
105
111
|
Sidekiq.remove_delay!
|
106
|
-
assert_equal 0,
|
112
|
+
assert_equal 0, q.size
|
107
113
|
assert_raises NoMethodError do
|
108
114
|
SomeModule.delay.doit(Date.today)
|
109
115
|
end
|
data/test/test_fetch.rb
CHANGED
@@ -20,7 +20,7 @@ class TestFetcher < Sidekiq::Test
|
|
20
20
|
uow = fetch.retrieve_work
|
21
21
|
refute_nil uow
|
22
22
|
assert_equal 'basic', uow.queue_name
|
23
|
-
assert_equal 'msg', uow.
|
23
|
+
assert_equal 'msg', uow.job
|
24
24
|
q = Sidekiq::Queue.new('basic')
|
25
25
|
assert_equal 0, q.size
|
26
26
|
uow.requeue
|
@@ -31,7 +31,7 @@ class TestFetcher < Sidekiq::Test
|
|
31
31
|
it 'retrieves with strict setting' do
|
32
32
|
fetch = Sidekiq::BasicFetch.new(:queues => ['basic', 'bar', 'bar'], :strict => true)
|
33
33
|
cmd = fetch.queues_cmd
|
34
|
-
assert_equal cmd, ['queue:basic', 'queue:bar',
|
34
|
+
assert_equal cmd, ['queue:basic', 'queue:bar', Sidekiq::BasicFetch::TIMEOUT]
|
35
35
|
end
|
36
36
|
|
37
37
|
it 'bulk requeues' do
|
@@ -45,60 +45,5 @@ class TestFetcher < Sidekiq::Test
|
|
45
45
|
assert_equal 1, q2.size
|
46
46
|
end
|
47
47
|
|
48
|
-
describe 'fetching' do
|
49
|
-
before do
|
50
|
-
Sidekiq::Fetcher.reset
|
51
|
-
end
|
52
|
-
|
53
|
-
it 'instantiates' do
|
54
|
-
begin
|
55
|
-
Sidekiq.options[:fetch] = NullFetch
|
56
|
-
mgr = Minitest::Mock.new
|
57
|
-
fetch = Sidekiq::Fetcher.new(mgr, {})
|
58
|
-
fetch.fetch
|
59
|
-
Sidekiq::Fetcher.done!
|
60
|
-
ensure
|
61
|
-
Sidekiq.options[:fetch] = Sidekiq::BasicFetch
|
62
|
-
end
|
63
|
-
end
|
64
|
-
|
65
|
-
class NullFetch
|
66
|
-
def initialize(opts)
|
67
|
-
end
|
68
|
-
def retrieve_work
|
69
|
-
end
|
70
|
-
def self.bulk_requeue(*args)
|
71
|
-
end
|
72
|
-
end
|
73
|
-
|
74
|
-
it 'handles redis network errors' do
|
75
|
-
begin
|
76
|
-
Sidekiq.logger.level = Logger::FATAL
|
77
|
-
Sidekiq.options[:fetch] = ErrorFetch
|
78
|
-
mgr = Minitest::Mock.new
|
79
|
-
fetch = Sidekiq::Fetcher.new(mgr, {})
|
80
|
-
def fetch.pause
|
81
|
-
end
|
82
|
-
refute fetch.down
|
83
|
-
fetch.fetch
|
84
|
-
Sidekiq::Fetcher.done!
|
85
|
-
assert fetch.down
|
86
|
-
ensure
|
87
|
-
Sidekiq.options[:fetch] = Sidekiq::BasicFetch
|
88
|
-
Sidekiq.logger.level = Logger::ERROR
|
89
|
-
end
|
90
|
-
end
|
91
|
-
|
92
|
-
class ErrorFetch
|
93
|
-
def initialize(opts)
|
94
|
-
end
|
95
|
-
def retrieve_work
|
96
|
-
raise IOError, "ker-BOOM"
|
97
|
-
end
|
98
|
-
def self.bulk_requeue(*args)
|
99
|
-
end
|
100
|
-
end
|
101
|
-
end
|
102
|
-
|
103
48
|
end
|
104
49
|
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
require_relative 'helper'
|
2
|
+
require 'sidekiq/launcher'
|
3
|
+
|
4
|
+
class TestLauncher < Sidekiq::Test
|
5
|
+
|
6
|
+
describe 'launcher' do
|
7
|
+
before do
|
8
|
+
Sidekiq.redis {|c| c.flushdb }
|
9
|
+
end
|
10
|
+
|
11
|
+
def new_manager(opts)
|
12
|
+
Sidekiq::Manager.new(opts)
|
13
|
+
end
|
14
|
+
|
15
|
+
describe 'heartbeat' do
|
16
|
+
before do
|
17
|
+
uow = Object.new
|
18
|
+
|
19
|
+
@mgr = new_manager(options)
|
20
|
+
@launcher = Sidekiq::Launcher.new(options)
|
21
|
+
@launcher.manager = @mgr
|
22
|
+
|
23
|
+
Sidekiq::Processor::WORKER_STATE['a'] = {'b' => 1}
|
24
|
+
|
25
|
+
@proctitle = $0
|
26
|
+
end
|
27
|
+
|
28
|
+
after do
|
29
|
+
Sidekiq::Processor::WORKER_STATE.clear
|
30
|
+
$0 = @proctitle
|
31
|
+
end
|
32
|
+
|
33
|
+
describe 'when manager is active' do
|
34
|
+
before do
|
35
|
+
Sidekiq::CLI::PROCTITLES << proc { "xyz" }
|
36
|
+
@launcher.heartbeat('identity', heartbeat_data, Sidekiq.dump_json(heartbeat_data))
|
37
|
+
Sidekiq::CLI::PROCTITLES.pop
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'sets useful info to proctitle' do
|
41
|
+
assert_equal "sidekiq #{Sidekiq::VERSION} myapp [1 of 3 busy] xyz", $0
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'stores process info in redis' do
|
45
|
+
info = Sidekiq.redis { |c| c.hmget('identity', 'busy') }
|
46
|
+
assert_equal ["1"], info
|
47
|
+
expires = Sidekiq.redis { |c| c.pttl('identity') }
|
48
|
+
assert_in_delta 60000, expires, 500
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
describe 'when manager is stopped' do
|
53
|
+
before do
|
54
|
+
@launcher.quiet
|
55
|
+
@launcher.heartbeat('identity', heartbeat_data, Sidekiq.dump_json(heartbeat_data))
|
56
|
+
end
|
57
|
+
|
58
|
+
it 'indicates stopping status in proctitle' do
|
59
|
+
assert_equal "sidekiq #{Sidekiq::VERSION} myapp [1 of 3 busy] stopping", $0
|
60
|
+
end
|
61
|
+
|
62
|
+
it 'stores process info in redis' do
|
63
|
+
info = Sidekiq.redis { |c| c.hmget('identity', 'busy') }
|
64
|
+
assert_equal ["1"], info
|
65
|
+
expires = Sidekiq.redis { |c| c.pttl('identity') }
|
66
|
+
assert_in_delta 60000, expires, 50
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def options
|
72
|
+
{ :concurrency => 3, :queues => ['default'] }
|
73
|
+
end
|
74
|
+
|
75
|
+
def heartbeat_data
|
76
|
+
{ 'concurrency' => 3, 'tag' => 'myapp' }
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
end
|