sidekiq 2.5.3 → 2.5.4
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.
- data/Changes.md +11 -1
- data/lib/sidekiq/api.rb +15 -0
- data/lib/sidekiq/cli.rb +12 -1
- data/lib/sidekiq/client.rb +13 -13
- data/lib/sidekiq/testing/inline.rb +5 -2
- data/lib/sidekiq/version.rb +1 -1
- data/lib/sidekiq/web.rb +13 -4
- data/test/test_api.rb +22 -2
- data/test/test_client.rb +22 -0
- data/test/test_scheduling.rb +6 -0
- data/test/test_testing_inline.rb +8 -0
- data/test/test_web.rb +25 -1
- data/web/assets/stylesheets/application.css +3 -3
- data/web/views/_nav.slim +6 -2
- data/web/views/retries.slim +8 -2
- metadata +2 -2
data/Changes.md
CHANGED
@@ -1,4 +1,14 @@
|
|
1
|
-
|
1
|
+
2.5.4
|
2
|
+
-----------
|
3
|
+
|
4
|
+
- `Sidekiq::Client.push` now accepts the worker class as a string so the
|
5
|
+
Sidekiq client does not have to load your worker classes at all. [#524]
|
6
|
+
- `Sidekiq::Client.push_bulk` now works with inline testing.
|
7
|
+
- **Really** fix status icon in Web UI this time.
|
8
|
+
- Add "Delete All" and "Retry All" buttons to Retries in Web UI
|
9
|
+
|
10
|
+
|
11
|
+
2.5.3
|
2
12
|
-----------
|
3
13
|
|
4
14
|
- Small Web UI fixes
|
data/lib/sidekiq/api.rb
CHANGED
@@ -43,6 +43,15 @@ module Sidekiq
|
|
43
43
|
end
|
44
44
|
end
|
45
45
|
end
|
46
|
+
|
47
|
+
def clear
|
48
|
+
Sidekiq.redis do |conn|
|
49
|
+
conn.multi do
|
50
|
+
conn.del("queue:#{name}")
|
51
|
+
conn.srem("queues", name)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
46
55
|
end
|
47
56
|
|
48
57
|
##
|
@@ -143,6 +152,12 @@ module Sidekiq
|
|
143
152
|
end
|
144
153
|
count != 0
|
145
154
|
end
|
155
|
+
|
156
|
+
def clear
|
157
|
+
Sidekiq.redis do |conn|
|
158
|
+
conn.del(@zset)
|
159
|
+
end
|
160
|
+
end
|
146
161
|
end
|
147
162
|
|
148
163
|
##
|
data/lib/sidekiq/cli.rb
CHANGED
@@ -126,12 +126,23 @@ module Sidekiq
|
|
126
126
|
require 'sidekiq/rails'
|
127
127
|
require File.expand_path("#{options[:require]}/config/environment.rb")
|
128
128
|
::Rails.application.eager_load!
|
129
|
-
options[:tag] ||=
|
129
|
+
options[:tag] ||= default_tag
|
130
130
|
else
|
131
131
|
require options[:require]
|
132
132
|
end
|
133
133
|
end
|
134
134
|
|
135
|
+
def default_tag
|
136
|
+
dir = ::Rails.root
|
137
|
+
name = File.basename(dir)
|
138
|
+
if name.to_i != 0 && prevdir = File.dirname(dir) # Capistrano release directory?
|
139
|
+
if File.basename(prevdir) == 'releases'
|
140
|
+
return File.basename(File.dirname(prevdir))
|
141
|
+
end
|
142
|
+
end
|
143
|
+
name
|
144
|
+
end
|
145
|
+
|
135
146
|
def validate!
|
136
147
|
options[:queues] << 'default' if options[:queues].empty?
|
137
148
|
|
data/lib/sidekiq/client.rb
CHANGED
@@ -65,13 +65,7 @@ module Sidekiq
|
|
65
65
|
end.compact
|
66
66
|
|
67
67
|
pushed = false
|
68
|
-
|
69
|
-
_, pushed = conn.multi do
|
70
|
-
conn.sadd('queues', normed['queue'])
|
71
|
-
conn.rpush("queue:#{normed['queue']}", payloads)
|
72
|
-
end
|
73
|
-
end
|
74
|
-
|
68
|
+
pushed = raw_push(normed, payloads)
|
75
69
|
pushed ? payloads.size : nil
|
76
70
|
end
|
77
71
|
|
@@ -98,7 +92,9 @@ module Sidekiq
|
|
98
92
|
def self.raw_push(normed, payload) # :nodoc:
|
99
93
|
pushed = false
|
100
94
|
Sidekiq.redis do |conn|
|
101
|
-
if normed['at']
|
95
|
+
if normed['at'] && payload.is_a?(Array)
|
96
|
+
pushed = conn.zadd('schedule', payload.map {|hash| [normed['at'].to_s, hash]})
|
97
|
+
elsif normed['at']
|
102
98
|
pushed = conn.zadd('schedule', normed['at'].to_s, payload)
|
103
99
|
else
|
104
100
|
_, pushed = conn.multi do
|
@@ -122,13 +118,17 @@ module Sidekiq
|
|
122
118
|
def self.normalize_item(item)
|
123
119
|
raise(ArgumentError, "Message must be a Hash of the form: { 'class' => SomeWorker, 'args' => ['bob', 1, :foo => 'bar'] }") unless item.is_a?(Hash)
|
124
120
|
raise(ArgumentError, "Message must include a class and set of arguments: #{item.inspect}") if !item['class'] || !item['args']
|
125
|
-
raise(ArgumentError, "Message must
|
121
|
+
raise(ArgumentError, "Message class must be either a Class or String representation of the class name") unless item['class'].is_a?(Class) || item['class'].is_a?(String)
|
122
|
+
|
123
|
+
if item['class'].is_a?(Class)
|
124
|
+
raise(ArgumentError, "Message must include a Sidekiq::Worker class, not class name: #{item['class'].ancestors.inspect}") if !item['class'].respond_to?('get_sidekiq_options')
|
125
|
+
normalized_item = item['class'].get_sidekiq_options.merge(item)
|
126
|
+
normalized_item['class'] = normalized_item['class'].to_s
|
127
|
+
else
|
128
|
+
normalized_item = Sidekiq::Worker::ClassMethods::DEFAULT_OPTIONS.merge(item)
|
129
|
+
end
|
126
130
|
|
127
|
-
normalized_item = item['class'].get_sidekiq_options.merge(item.dup)
|
128
|
-
normalized_item['class'] = normalized_item['class'].to_s
|
129
|
-
normalized_item['retry'] = !!normalized_item['retry'] unless normalized_item['retry'].is_a?(Fixnum)
|
130
131
|
normalized_item['jid'] = SecureRandom.hex(12)
|
131
|
-
|
132
132
|
normalized_item
|
133
133
|
end
|
134
134
|
|
@@ -28,8 +28,11 @@ module Sidekiq
|
|
28
28
|
#
|
29
29
|
singleton_class.class_eval do
|
30
30
|
alias_method :raw_push_old, :raw_push
|
31
|
-
def raw_push(
|
32
|
-
|
31
|
+
def raw_push(normed, payload)
|
32
|
+
Array.wrap(payload).each do |hash|
|
33
|
+
normed['class'].constantize.new.perform(*Sidekiq.load_json(hash)['args'])
|
34
|
+
end
|
35
|
+
|
33
36
|
true
|
34
37
|
end
|
35
38
|
end
|
data/lib/sidekiq/version.rb
CHANGED
data/lib/sidekiq/web.rb
CHANGED
@@ -136,10 +136,7 @@ module Sidekiq
|
|
136
136
|
end
|
137
137
|
|
138
138
|
post "/queues/:name" do
|
139
|
-
Sidekiq.
|
140
|
-
conn.del("queue:#{params[:name]}")
|
141
|
-
conn.srem("queues", params[:name])
|
142
|
-
end
|
139
|
+
Sidekiq::Queue.new(params[:name]).clear
|
143
140
|
redirect "#{root_path}queues"
|
144
141
|
end
|
145
142
|
|
@@ -195,6 +192,18 @@ module Sidekiq
|
|
195
192
|
redirect "#{root_path}retries"
|
196
193
|
end
|
197
194
|
|
195
|
+
post "/retries/all/delete" do
|
196
|
+
Sidekiq::RetrySet.new.clear
|
197
|
+
redirect "#{root_path}retries"
|
198
|
+
end
|
199
|
+
|
200
|
+
post "/retries/all/retry" do
|
201
|
+
Sidekiq::RetrySet.new.each do |job|
|
202
|
+
process_score('retry', job.score, :retry)
|
203
|
+
end
|
204
|
+
redirect "#{root_path}retries"
|
205
|
+
end
|
206
|
+
|
198
207
|
post "/retries/:score" do
|
199
208
|
halt 404 unless params[:score]
|
200
209
|
score = params[:score].to_f
|
data/test/test_api.rb
CHANGED
@@ -36,6 +36,17 @@ class TestApi < MiniTest::Unit::TestCase
|
|
36
36
|
assert_equal 0, q.size
|
37
37
|
end
|
38
38
|
|
39
|
+
it 'can clear a queue' do
|
40
|
+
q = Sidekiq::Queue.new
|
41
|
+
2.times { ApiWorker.perform_async(1, 'mike') }
|
42
|
+
q.clear
|
43
|
+
|
44
|
+
Sidekiq.redis do |conn|
|
45
|
+
refute conn.smembers('queues').include?('foo')
|
46
|
+
refute conn.exists('queues:foo')
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
39
50
|
it 'shows empty retries' do
|
40
51
|
r = Sidekiq::RetrySet.new
|
41
52
|
assert_equal 0, r.size
|
@@ -64,9 +75,18 @@ class TestApi < MiniTest::Unit::TestCase
|
|
64
75
|
assert_equal 0, r.size
|
65
76
|
end
|
66
77
|
|
67
|
-
|
78
|
+
it 'can clear retries' do
|
79
|
+
add_retry
|
80
|
+
add_retry('test')
|
81
|
+
r = Sidekiq::RetrySet.new
|
82
|
+
assert_equal 2, r.size
|
83
|
+
r.clear
|
84
|
+
assert_equal 0, r.size
|
85
|
+
end
|
86
|
+
|
87
|
+
def add_retry(jid = 'bob')
|
68
88
|
at = Time.now.to_f
|
69
|
-
payload = Sidekiq.dump_json('class' => 'ApiWorker', 'args' => [1, 'mike'], 'queue' => 'default', 'jid' =>
|
89
|
+
payload = Sidekiq.dump_json('class' => 'ApiWorker', 'args' => [1, 'mike'], 'queue' => 'default', 'jid' => jid)
|
70
90
|
Sidekiq.redis do |conn|
|
71
91
|
conn.zadd('retry', at.to_s, payload)
|
72
92
|
end
|
data/test/test_client.rb
CHANGED
@@ -30,6 +30,15 @@ class TestClient < MiniTest::Unit::TestCase
|
|
30
30
|
assert_raises ArgumentError do
|
31
31
|
Sidekiq::Client.push('foo', :class => 'Foo', :noargs => [1, 2])
|
32
32
|
end
|
33
|
+
|
34
|
+
assert_raises ArgumentError do
|
35
|
+
Sidekiq::Client.push('queue' => 'foo', 'class' => MyWorker, 'noargs' => [1, 2])
|
36
|
+
end
|
37
|
+
|
38
|
+
assert_raises ArgumentError do
|
39
|
+
Sidekiq::Client.push('queue' => 'foo', 'class' => 42, 'args' => [1, 2])
|
40
|
+
end
|
41
|
+
|
33
42
|
end
|
34
43
|
|
35
44
|
it 'pushes messages to redis' do
|
@@ -40,6 +49,14 @@ class TestClient < MiniTest::Unit::TestCase
|
|
40
49
|
@redis.verify
|
41
50
|
end
|
42
51
|
|
52
|
+
it 'pushes messages to redis using a String class' do
|
53
|
+
@redis.expect :rpush, 1, ['queue:foo', String]
|
54
|
+
pushed = Sidekiq::Client.push('queue' => 'foo', 'class' => 'MyWorker', 'args' => [1, 2])
|
55
|
+
assert pushed
|
56
|
+
assert_equal 24, pushed.size
|
57
|
+
@redis.verify
|
58
|
+
end
|
59
|
+
|
43
60
|
class MyWorker
|
44
61
|
include Sidekiq::Worker
|
45
62
|
end
|
@@ -105,6 +122,11 @@ class TestClient < MiniTest::Unit::TestCase
|
|
105
122
|
count = Sidekiq::Client.push_bulk('class' => QueuedWorker, 'args' => (1..1_000).to_a.map { |x| Array(x) })
|
106
123
|
assert_equal 1_000, count
|
107
124
|
end
|
125
|
+
it 'can push a large set of jobs at once using a String class' do
|
126
|
+
a = Time.now
|
127
|
+
count = Sidekiq::Client.push_bulk('class' => 'QueuedWorker', 'args' => (1..1_000).to_a.map { |x| Array(x) })
|
128
|
+
assert_equal 1_000, count
|
129
|
+
end
|
108
130
|
end
|
109
131
|
|
110
132
|
class BaseWorker
|
data/test/test_scheduling.rb
CHANGED
@@ -28,6 +28,12 @@ class TestScheduling < MiniTest::Unit::TestCase
|
|
28
28
|
assert ScheduledWorker.perform_in(5.days.from_now, 'mike')
|
29
29
|
@redis.verify
|
30
30
|
end
|
31
|
+
|
32
|
+
it 'schedules multiple jobs at once' do
|
33
|
+
@redis.expect :zadd, true, ['schedule', Array]
|
34
|
+
assert Sidekiq::Client.push_bulk('class' => ScheduledWorker, 'args' => ['mike', 'mike'], 'at' => 600)
|
35
|
+
@redis.verify
|
36
|
+
end
|
31
37
|
end
|
32
38
|
|
33
39
|
end
|
data/test/test_testing_inline.rb
CHANGED
@@ -80,6 +80,14 @@ class TestInline < MiniTest::Unit::TestCase
|
|
80
80
|
end
|
81
81
|
end
|
82
82
|
|
83
|
+
it 'stubs the push_bulk call when in testing mode' do
|
84
|
+
assert Sidekiq::Client.push_bulk({'class' => InlineWorker, 'args' => [true, true]})
|
85
|
+
|
86
|
+
assert_raises InlineError do
|
87
|
+
Sidekiq::Client.push_bulk({'class' => InlineWorker, 'args' => [true, false]})
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
83
91
|
it 'should relay parameters through json' do
|
84
92
|
assert Sidekiq::Client.enqueue(InlineWorkerWithTimeParam, Time.now)
|
85
93
|
end
|
data/test/test_web.rb
CHANGED
@@ -72,9 +72,10 @@ class TestWeb < MiniTest::Unit::TestCase
|
|
72
72
|
|
73
73
|
Sidekiq.redis do |conn|
|
74
74
|
refute conn.smembers('queues').include?('foo')
|
75
|
+
refute conn.exists('queues:foo')
|
75
76
|
end
|
76
77
|
end
|
77
|
-
|
78
|
+
|
78
79
|
it 'can delete a job' do
|
79
80
|
Sidekiq.redis do |conn|
|
80
81
|
conn.rpush('queue:foo', "{}")
|
@@ -154,6 +155,15 @@ class TestWeb < MiniTest::Unit::TestCase
|
|
154
155
|
refute_match /#{score}/, last_response.body
|
155
156
|
end
|
156
157
|
|
158
|
+
it 'can delete all retries' do
|
159
|
+
3.times { add_retry }
|
160
|
+
|
161
|
+
post "/retries/all/delete", 'delete' => 'Delete'
|
162
|
+
assert_equal 0, Sidekiq::RetrySet.new.size
|
163
|
+
assert_equal 302, last_response.status
|
164
|
+
assert_equal 'http://example.org/retries', last_response.header['Location']
|
165
|
+
end
|
166
|
+
|
157
167
|
it 'can retry a single retry now' do
|
158
168
|
msg, score = add_retry
|
159
169
|
|
@@ -166,6 +176,20 @@ class TestWeb < MiniTest::Unit::TestCase
|
|
166
176
|
assert_match /#{msg['args'][2]}/, last_response.body
|
167
177
|
end
|
168
178
|
|
179
|
+
it 'can retry all retries' do
|
180
|
+
msg, score = add_retry
|
181
|
+
add_retry
|
182
|
+
|
183
|
+
post "/retries/all/retry", 'retry' => 'Retry'
|
184
|
+
assert_equal 302, last_response.status
|
185
|
+
assert_equal 'http://example.org/retries', last_response.header['Location']
|
186
|
+
assert_equal 2, Sidekiq::Queue.new("default").size
|
187
|
+
|
188
|
+
get '/queues/default'
|
189
|
+
assert_equal 200, last_response.status
|
190
|
+
assert_match /#{msg['args'][2]}/, last_response.body
|
191
|
+
end
|
192
|
+
|
169
193
|
it 'can show user defined tab' do
|
170
194
|
begin
|
171
195
|
Sidekiq::Web.tabs['Custom Tab'] = '/custom'
|
@@ -216,12 +216,12 @@ header.row .pagination {
|
|
216
216
|
padding: 4px 0 2px 0;
|
217
217
|
}
|
218
218
|
.summary_bar ul .desc {
|
219
|
-
font-size:
|
219
|
+
font-size: 1em;
|
220
220
|
font-weight: normal;
|
221
221
|
}
|
222
222
|
.summary_bar ul .count {
|
223
223
|
color: #b1003e;
|
224
|
-
font-size:
|
224
|
+
font-size: 1em;
|
225
225
|
font-weight: bold;
|
226
226
|
float: right;
|
227
227
|
}
|
@@ -447,7 +447,7 @@ img.smallogo {
|
|
447
447
|
}
|
448
448
|
|
449
449
|
.status-sprite {
|
450
|
-
background-image: url(
|
450
|
+
background-image: url(../images/status-sd8051fd480.png);
|
451
451
|
height: 30px;
|
452
452
|
width: 30px;
|
453
453
|
display: inline-block;
|
data/web/views/_nav.slim
CHANGED
@@ -9,5 +9,9 @@
|
|
9
9
|
div.nav-collapse
|
10
10
|
ul.nav
|
11
11
|
- tabs.each do |title, url|
|
12
|
-
|
13
|
-
|
12
|
+
- if url.blank?
|
13
|
+
li class="#{(current_path == url) ? 'active':''}"
|
14
|
+
a href='#{{root_path}}#{{url}}' #{title}
|
15
|
+
- else
|
16
|
+
li class="#{(current_path =~ Regexp.new(url)) ? 'active':''}"
|
17
|
+
a href='#{{root_path}}#{{url}}' #{title}
|
data/web/views/retries.slim
CHANGED
@@ -28,7 +28,13 @@ header.row
|
|
28
28
|
a href="#{root_path}queues/#{msg['queue']}" #{msg['queue']}
|
29
29
|
td= msg['class']
|
30
30
|
td= display_args(msg['args'])
|
31
|
-
input.btn.btn-
|
32
|
-
input.btn.btn-
|
31
|
+
input.btn.btn-primary.btn-small.pull-left type="submit" name="retry" value="Retry Now"
|
32
|
+
input.btn.btn-danger.btn-small.pull-left type="submit" name="delete" value="Delete"
|
33
|
+
|
34
|
+
form action="#{root_path}retries/all/delete" method="post"
|
35
|
+
input.btn.btn-danger.btn-small.pull-right type="submit" name="delete" value="Delete All" data-confirm="Are you sure?"
|
36
|
+
form action="#{root_path}retries/all/retry" method="post"
|
37
|
+
input.btn.btn-danger.btn-small.pull-right type="submit" name="retry" value="Retry All" data-confirm="Are you sure?"
|
38
|
+
|
33
39
|
- else
|
34
40
|
.alert.alert-success No retries were found
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sidekiq
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.5.
|
4
|
+
version: 2.5.4
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-11-
|
12
|
+
date: 2012-11-27 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: redis
|