sidekiq 4.0.1 → 4.0.2
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/.travis.yml +3 -2
- data/4.0-Upgrade.md +10 -0
- data/Changes.md +17 -1
- data/Ent-Changes.md +14 -1
- data/Pro-Changes.md +1 -6
- data/README.md +13 -8
- data/bin/sidekiq +0 -1
- data/lib/generators/sidekiq/templates/worker_spec.rb.erb +2 -2
- data/lib/generators/sidekiq/templates/worker_test.rb.erb +5 -5
- data/lib/sidekiq/api.rb +14 -2
- data/lib/sidekiq/fetch.rb +1 -1
- data/lib/sidekiq/manager.rb +5 -3
- data/lib/sidekiq/middleware/server/logging.rb +3 -3
- data/lib/sidekiq/middleware/server/retry_jobs.rb +1 -1
- data/lib/sidekiq/testing.rb +127 -14
- data/lib/sidekiq/version.rb +1 -1
- data/lib/sidekiq/web.rb +1 -1
- data/lib/sidekiq/web_helpers.rb +7 -1
- data/lib/sidekiq/worker.rb +2 -0
- data/sidekiq.gemspec +0 -1
- data/test/test_api.rb +33 -0
- data/test/test_testing_fake.rb +79 -1
- data/test/test_web.rb +11 -6
- data/web/locales/en.yml +1 -0
- data/web/locales/fr.yml +2 -2
- data/web/locales/ja.yml +10 -1
- data/web/views/_job_info.erb +4 -0
- metadata +3 -17
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 981fa47de9add237cde6413d7e97aa70726ae757
|
4
|
+
data.tar.gz: 52151d63cf02724358c925155d8f3471f453fe75
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 977c16381346d0fea1968ecd4d8efd2a5b900e0a0a4e4017c21fddeb910977b716959a7d8cb6515260ee4da4f58fe645a13a75b0985663594798e2f80980dcea
|
7
|
+
data.tar.gz: 2852d63ccf3686dfa438d468fdc6593ad25cd95c2f727d0c0e71625ab0c6fa42af394826105a0b7a12d103c635ea6beff8d2fb757e2ea53ef7bfb8c8785ad6e0
|
data/.travis.yml
CHANGED
data/4.0-Upgrade.md
CHANGED
@@ -25,6 +25,16 @@ gem 'redis-namespace'
|
|
25
25
|
`concurrency + 2` connections in your pool or Sidekiq will exit.
|
26
26
|
When in doubt, let Sidekiq size the connection pool for you.
|
27
27
|
|
28
|
+
* There's a new testing API based off the `Sidekiq::Queues` namespace. All
|
29
|
+
assertions made against the Worker class still work as expected.
|
30
|
+
```ruby
|
31
|
+
assert_equal 0, Sidekiq::Queues["default"].size
|
32
|
+
HardWorker.perform_async("log")
|
33
|
+
assert_equal 1, Sidekiq::Queues["default"].size
|
34
|
+
assert_equal "log", Sidekiq::Queues["default"].first['args'][0]
|
35
|
+
Sidekiq::Queues.clear_all
|
36
|
+
```
|
37
|
+
|
28
38
|
## Upgrade
|
29
39
|
|
30
40
|
First, make sure you are using Redis 2.8 or greater. Next:
|
data/Changes.md
CHANGED
@@ -1,5 +1,21 @@
|
|
1
1
|
# Sidekiq Changes
|
2
2
|
|
3
|
+
4.0.2
|
4
|
+
-----------
|
5
|
+
|
6
|
+
- Better Japanese translations
|
7
|
+
- Remove `json` gem dependency from gemspec. [#2743]
|
8
|
+
- There's a new testing API based off the `Sidekiq::Queues` namespace. All
|
9
|
+
assertions made against the Worker class still work as expected.
|
10
|
+
[#2676, brandonhilkert]
|
11
|
+
```ruby
|
12
|
+
assert_equal 0, Sidekiq::Queues["default"].size
|
13
|
+
HardWorker.perform_async("log")
|
14
|
+
assert_equal 1, Sidekiq::Queues["default"].size
|
15
|
+
assert_equal "log", Sidekiq::Queues["default"].first['args'][0]
|
16
|
+
Sidekiq::Queues.clear_all
|
17
|
+
```
|
18
|
+
|
3
19
|
4.0.1
|
4
20
|
-----------
|
5
21
|
|
@@ -41,7 +57,7 @@
|
|
41
57
|
-----------
|
42
58
|
|
43
59
|
- **FIX MEMORY LEAK** Under rare conditions, threads may leak [#2598, gazay]
|
44
|
-
- Add
|
60
|
+
- Add Ukrainian locale [#2561, elrakita]
|
45
61
|
- Disconnect and retry Redis operations if we see a READONLY error [#2550]
|
46
62
|
- Add server middleware testing harness; see [wiki](https://github.com/mperham/sidekiq/wiki/Testing#testing-server-middleware) [#2534, ryansch]
|
47
63
|
|
data/Ent-Changes.md
CHANGED
@@ -3,7 +3,20 @@ Sidekiq Enterprise Changelog
|
|
3
3
|
|
4
4
|
Please see [http://sidekiq.org/](http://sidekiq.org/) for more details and how to buy.
|
5
5
|
|
6
|
-
1.0.
|
6
|
+
0.7.9, 1.0.2
|
7
|
+
-------------
|
8
|
+
|
9
|
+
- Window limiters can now accept arbitrary window sizes [#2686]
|
10
|
+
- Fix race condition in window limiters leading to non-stop OverLimit [#2704]
|
11
|
+
- Fix invalid overage counts when nesting concurrent limiters
|
12
|
+
|
13
|
+
1.0.1
|
14
|
+
----------
|
15
|
+
|
16
|
+
- Fix crash in periodic subsystem when a follower shuts down, thanks
|
17
|
+
to @justinko for reporting.
|
18
|
+
|
19
|
+
1.0.0
|
7
20
|
----------
|
8
21
|
|
9
22
|
- Enterprise 1.x targets Sidekiq 4.x.
|
data/Pro-Changes.md
CHANGED
@@ -3,12 +3,7 @@ Sidekiq Pro Changelog
|
|
3
3
|
|
4
4
|
Please see [http://sidekiq.org/](http://sidekiq.org/) for more details and how to buy.
|
5
5
|
|
6
|
-
3.0.0
|
7
|
-
-----------
|
8
|
-
|
9
|
-
- Fix excessive connection usage by reliable fetch.
|
10
|
-
|
11
|
-
3.0.0.pre1
|
6
|
+
3.0.0
|
12
7
|
-----------
|
13
8
|
|
14
9
|
- See the [Pro 3.0 release notes](Pro-3.0-Upgrade.md).
|
data/README.md
CHANGED
@@ -18,21 +18,26 @@ message format as Resque so it can integrate into an existing Resque processing
|
|
18
18
|
You can have Sidekiq and Resque run side-by-side at the same time and
|
19
19
|
use the Resque client to enqueue jobs in Redis to be processed by Sidekiq.
|
20
20
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
21
|
+
Sidekiq is fast.
|
22
|
+
|
23
|
+
Version | Latency | Garbage created for 10,000 jobs | Time to process 100,000 jobs | Throughput
|
24
|
+
-----------------|------|---------|---------|------------------------
|
25
|
+
Sidekiq 4.0.0 | 10ms | 151 MB | 22 sec | **4500 jobs/sec**
|
26
|
+
Sidekiq 3.5.1 | 22ms | 1257 MB | 125 sec | 800 jobs/sec
|
27
|
+
Resque 1.25.2 | - | - | 420 sec | 240 jobs/sec
|
28
|
+
DelayedJob 4.1.1 | - | - | 465 sec | 215 jobs/sec
|
25
29
|
|
26
30
|
|
27
31
|
Requirements
|
28
32
|
-----------------
|
29
33
|
|
30
|
-
I test with the latest
|
31
|
-
are untested but might work fine.
|
34
|
+
I test with the latest CRuby (2.2, 2.1 and 2.0) and JRuby versions (9k). Other versions/VMs
|
35
|
+
are untested but might work fine. CRuby 1.9 is not supported.
|
32
36
|
|
33
|
-
All Rails releases
|
37
|
+
All Rails releases from 3.2 are officially supported.
|
34
38
|
|
35
|
-
Redis 2.8 or greater is required.
|
39
|
+
Redis 2.8 or greater is required. 3.0.3+ is recommended for large
|
40
|
+
installations with thousands of worker threads.
|
36
41
|
|
37
42
|
|
38
43
|
Installation
|
data/bin/sidekiq
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
require_relative 'test_helper'
|
2
2
|
<% module_namespacing do -%>
|
3
|
-
class <%= class_name %>WorkerTest < MiniTest::Unit::TestCase
|
4
|
-
|
5
|
-
|
6
|
-
|
3
|
+
class <%= class_name %>WorkerTest < <% if defined? Minitest::Test %>Minitest::Test<% else %>MiniTest::Unit::TestCase<% end %>
|
4
|
+
def test_example
|
5
|
+
skip "add some examples to (or delete) #{__FILE__}"
|
6
|
+
end
|
7
7
|
end
|
8
|
-
<% end -%>
|
8
|
+
<% end -%>
|
data/lib/sidekiq/api.rb
CHANGED
@@ -283,7 +283,13 @@ module Sidekiq
|
|
283
283
|
"#{target}.#{method}"
|
284
284
|
end
|
285
285
|
when "ActiveJob::QueueAdapters::SidekiqAdapter::JobWrapper"
|
286
|
-
@item['wrapped'] || args[0]
|
286
|
+
job_class = @item['wrapped'] || args[0]
|
287
|
+
if 'ActionMailer::DeliveryJob' == job_class
|
288
|
+
# MailerClass#mailer_method
|
289
|
+
args[0]['arguments'][0..1].join('#')
|
290
|
+
else
|
291
|
+
job_class
|
292
|
+
end
|
287
293
|
else
|
288
294
|
klass
|
289
295
|
end
|
@@ -297,7 +303,13 @@ module Sidekiq
|
|
297
303
|
arg
|
298
304
|
end
|
299
305
|
when "ActiveJob::QueueAdapters::SidekiqAdapter::JobWrapper"
|
300
|
-
@item['wrapped'] ? args[0]["arguments"] : []
|
306
|
+
job_args = @item['wrapped'] ? args[0]["arguments"] : []
|
307
|
+
if 'ActionMailer::DeliveryJob' == (@item['wrapped'] || args[0])
|
308
|
+
# remove MailerClass, mailer_method and 'deliver_now'
|
309
|
+
job_args.drop(3)
|
310
|
+
else
|
311
|
+
job_args
|
312
|
+
end
|
301
313
|
else
|
302
314
|
args
|
303
315
|
end
|
data/lib/sidekiq/fetch.rb
CHANGED
data/lib/sidekiq/manager.rb
CHANGED
@@ -55,6 +55,8 @@ module Sidekiq
|
|
55
55
|
fire_event(:quiet, true)
|
56
56
|
end
|
57
57
|
|
58
|
+
PAUSE_TIME = $TESTING ? 0.1 : 0.5
|
59
|
+
|
58
60
|
def stop(deadline)
|
59
61
|
quiet
|
60
62
|
fire_event(:shutdown, true)
|
@@ -62,14 +64,14 @@ module Sidekiq
|
|
62
64
|
# some of the shutdown events can be async,
|
63
65
|
# we don't have any way to know when they're done but
|
64
66
|
# give them a little time to take effect
|
65
|
-
sleep
|
67
|
+
sleep PAUSE_TIME
|
66
68
|
return if @workers.empty?
|
67
69
|
|
68
70
|
logger.info { "Pausing to allow workers to finish..." }
|
69
71
|
remaining = deadline - Time.now
|
70
|
-
while remaining >
|
72
|
+
while remaining > PAUSE_TIME
|
71
73
|
return if @workers.empty?
|
72
|
-
sleep
|
74
|
+
sleep PAUSE_TIME
|
73
75
|
remaining = deadline - Time.now
|
74
76
|
end
|
75
77
|
return if @workers.empty?
|
@@ -7,11 +7,11 @@ module Sidekiq
|
|
7
7
|
Sidekiq::Logging.with_context(log_context(worker, item)) do
|
8
8
|
begin
|
9
9
|
start = Time.now
|
10
|
-
logger.info
|
10
|
+
logger.info("start".freeze)
|
11
11
|
yield
|
12
|
-
logger.info
|
12
|
+
logger.info("done: #{elapsed(start)} sec")
|
13
13
|
rescue Exception
|
14
|
-
logger.info
|
14
|
+
logger.info("fail: #{elapsed(start)} sec")
|
15
15
|
raise
|
16
16
|
end
|
17
17
|
end
|
@@ -96,7 +96,7 @@ module Sidekiq
|
|
96
96
|
|
97
97
|
# App code can stuff all sorts of crazy binary data into the error message
|
98
98
|
# that won't convert to JSON.
|
99
|
-
m = exception.message[0
|
99
|
+
m = exception.message.to_s[0, 10_000]
|
100
100
|
if m.respond_to?(:scrub!)
|
101
101
|
m.force_encoding("utf-8")
|
102
102
|
m.scrub!
|
data/lib/sidekiq/testing.rb
CHANGED
@@ -68,15 +68,15 @@ module Sidekiq
|
|
68
68
|
def raw_push(payloads)
|
69
69
|
if Sidekiq::Testing.fake?
|
70
70
|
payloads.each do |job|
|
71
|
-
job['class']
|
71
|
+
Queues.push(job['queue'], job['class'], Sidekiq.load_json(Sidekiq.dump_json(job)))
|
72
72
|
end
|
73
73
|
true
|
74
74
|
elsif Sidekiq::Testing.inline?
|
75
75
|
payloads.each do |job|
|
76
|
-
job['jid'] ||= SecureRandom.hex(12)
|
77
76
|
klass = job['class'].constantize
|
78
|
-
|
79
|
-
|
77
|
+
job['id'] ||= SecureRandom.hex(12)
|
78
|
+
job_hash = Sidekiq.load_json(Sidekiq.dump_json(job))
|
79
|
+
klass.process_job(job_hash)
|
80
80
|
end
|
81
81
|
true
|
82
82
|
else
|
@@ -85,6 +85,107 @@ module Sidekiq
|
|
85
85
|
end
|
86
86
|
end
|
87
87
|
|
88
|
+
module Queues
|
89
|
+
##
|
90
|
+
# The Queues class is only for testing the fake queue implementation.
|
91
|
+
# There are 2 data structures involved in tandem. This is due to the
|
92
|
+
# Rspec syntax of change(QueueWorker.jobs, :size). It keeps a reference
|
93
|
+
# to the array. Because the array was dervied from a filter of the total
|
94
|
+
# jobs enqueued, it appeared as though the array didn't change.
|
95
|
+
#
|
96
|
+
# To solve this, we'll keep 2 hashes containing the jobs. One with keys based
|
97
|
+
# on the queue, and another with keys of the worker names, so the array for
|
98
|
+
# QueueWorker.jobs is a straight reference to a real array.
|
99
|
+
#
|
100
|
+
# Queue-based hash:
|
101
|
+
#
|
102
|
+
# {
|
103
|
+
# "default"=>[
|
104
|
+
# {
|
105
|
+
# "class"=>"TestTesting::QueueWorker",
|
106
|
+
# "args"=>[1, 2],
|
107
|
+
# "retry"=>true,
|
108
|
+
# "queue"=>"default",
|
109
|
+
# "jid"=>"abc5b065c5c4b27fc1102833",
|
110
|
+
# "created_at"=>1447445554.419934
|
111
|
+
# }
|
112
|
+
# ]
|
113
|
+
# }
|
114
|
+
#
|
115
|
+
# Worker-based hash:
|
116
|
+
#
|
117
|
+
# {
|
118
|
+
# "TestTesting::QueueWorker"=>[
|
119
|
+
# {
|
120
|
+
# "class"=>"TestTesting::QueueWorker",
|
121
|
+
# "args"=>[1, 2],
|
122
|
+
# "retry"=>true,
|
123
|
+
# "queue"=>"default",
|
124
|
+
# "jid"=>"abc5b065c5c4b27fc1102833",
|
125
|
+
# "created_at"=>1447445554.419934
|
126
|
+
# }
|
127
|
+
# ]
|
128
|
+
# }
|
129
|
+
#
|
130
|
+
# Example:
|
131
|
+
#
|
132
|
+
# require 'sidekiq/testing'
|
133
|
+
#
|
134
|
+
# assert_equal 0, Sidekiq::Queues["default"].size
|
135
|
+
# HardWorker.perform_async(:something)
|
136
|
+
# assert_equal 1, Sidekiq::Queues["default"].size
|
137
|
+
# assert_equal :something, Sidekiq::Queues["default"].first['args'][0]
|
138
|
+
#
|
139
|
+
# You can also clear all workers' jobs:
|
140
|
+
#
|
141
|
+
# assert_equal 0, Sidekiq::Queues["default"].size
|
142
|
+
# HardWorker.perform_async(:something)
|
143
|
+
# Sidekiq::Queues.clear_all
|
144
|
+
# assert_equal 0, Sidekiq::Queues["default"].size
|
145
|
+
#
|
146
|
+
# This can be useful to make sure jobs don't linger between tests:
|
147
|
+
#
|
148
|
+
# RSpec.configure do |config|
|
149
|
+
# config.before(:each) do
|
150
|
+
# Sidekiq::Queues.clear_all
|
151
|
+
# end
|
152
|
+
# end
|
153
|
+
#
|
154
|
+
class << self
|
155
|
+
def [](queue)
|
156
|
+
jobs_by_queue[queue]
|
157
|
+
end
|
158
|
+
|
159
|
+
def push(queue, klass, job)
|
160
|
+
jobs_by_queue[queue] << job
|
161
|
+
jobs_by_worker[klass] << job
|
162
|
+
end
|
163
|
+
|
164
|
+
def jobs_by_queue
|
165
|
+
@jobs_by_queue ||= Hash.new { |hash, key| hash[key] = [] }
|
166
|
+
end
|
167
|
+
|
168
|
+
def jobs_by_worker
|
169
|
+
@jobs_by_worker ||= Hash.new { |hash, key| hash[key] = [] }
|
170
|
+
end
|
171
|
+
|
172
|
+
def delete_for(jid, queue, klass)
|
173
|
+
jobs_by_queue[queue].delete_if { |job| job["jid"] == jid }
|
174
|
+
jobs_by_worker[klass].delete_if { |job| job["jid"] == jid }
|
175
|
+
end
|
176
|
+
|
177
|
+
def clear_for(queue, klass)
|
178
|
+
jobs_by_queue[queue].clear
|
179
|
+
jobs_by_worker[klass].clear
|
180
|
+
end
|
181
|
+
|
182
|
+
def clear_all
|
183
|
+
jobs_by_queue.clear
|
184
|
+
jobs_by_worker.clear
|
185
|
+
end
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
88
189
|
module Worker
|
89
190
|
##
|
90
191
|
# The Sidekiq testing infrastructure overrides perform_async
|
@@ -143,28 +244,36 @@ module Sidekiq
|
|
143
244
|
#
|
144
245
|
module ClassMethods
|
145
246
|
|
247
|
+
# Queue for this worker
|
248
|
+
def queue
|
249
|
+
self.sidekiq_options["queue"]
|
250
|
+
end
|
251
|
+
|
146
252
|
# Jobs queued for this worker
|
147
253
|
def jobs
|
148
|
-
|
254
|
+
Queues.jobs_by_worker[self.to_s]
|
149
255
|
end
|
150
256
|
|
151
257
|
# Clear all jobs for this worker
|
152
258
|
def clear
|
153
|
-
|
259
|
+
Queues.clear_for(queue, self.to_s)
|
154
260
|
end
|
155
261
|
|
156
262
|
# Drain and run all jobs for this worker
|
157
263
|
def drain
|
158
|
-
while
|
159
|
-
|
264
|
+
while jobs.any?
|
265
|
+
next_job = jobs.first
|
266
|
+
Queues.delete_for(next_job["jid"], queue, self.to_s)
|
267
|
+
process_job(next_job)
|
160
268
|
end
|
161
269
|
end
|
162
270
|
|
163
271
|
# Pop out a single job and perform it
|
164
272
|
def perform_one
|
165
273
|
raise(EmptyQueueError, "perform_one called with empty job queue") if jobs.empty?
|
166
|
-
|
167
|
-
|
274
|
+
next_job = jobs.first
|
275
|
+
Queues.delete_for(next_job["jid"], queue, self.to_s)
|
276
|
+
process_job(next_job)
|
168
277
|
end
|
169
278
|
|
170
279
|
def process_job(job)
|
@@ -183,18 +292,22 @@ module Sidekiq
|
|
183
292
|
|
184
293
|
class << self
|
185
294
|
def jobs # :nodoc:
|
186
|
-
|
295
|
+
Queues.jobs_by_queue.values.flatten
|
187
296
|
end
|
188
297
|
|
189
298
|
# Clear all queued jobs across all workers
|
190
299
|
def clear_all
|
191
|
-
|
300
|
+
Queues.clear_all
|
192
301
|
end
|
193
302
|
|
194
303
|
# Drain all queued jobs across all workers
|
195
304
|
def drain_all
|
196
|
-
|
197
|
-
jobs.
|
305
|
+
while jobs.any?
|
306
|
+
worker_classes = jobs.map { |job| job["class"] }.uniq
|
307
|
+
|
308
|
+
worker_classes.each do |worker_class|
|
309
|
+
worker_class.constantize.drain
|
310
|
+
end
|
198
311
|
end
|
199
312
|
end
|
200
313
|
end
|
data/lib/sidekiq/version.rb
CHANGED
data/lib/sidekiq/web.rb
CHANGED
@@ -12,7 +12,7 @@ module Sidekiq
|
|
12
12
|
include Sidekiq::Paginator
|
13
13
|
|
14
14
|
enable :sessions
|
15
|
-
use Rack::Protection, :use => :authenticity_token unless ENV['RACK_ENV'] == 'test'
|
15
|
+
use ::Rack::Protection, :use => :authenticity_token unless ENV['RACK_ENV'] == 'test'
|
16
16
|
|
17
17
|
set :root, File.expand_path(File.dirname(__FILE__) + "/../../web")
|
18
18
|
set :public_folder, proc { "#{root}/assets" }
|
data/lib/sidekiq/web_helpers.rb
CHANGED
@@ -17,8 +17,13 @@ module Sidekiq
|
|
17
17
|
end
|
18
18
|
end
|
19
19
|
|
20
|
+
def clear_caches
|
21
|
+
@@strings = nil
|
22
|
+
@@locale_files = nil
|
23
|
+
end
|
24
|
+
|
20
25
|
def locale_files
|
21
|
-
@@locale_files
|
26
|
+
@@locale_files ||= settings.locales.flat_map do |path|
|
22
27
|
Dir["#{path}/*.yml"]
|
23
28
|
end
|
24
29
|
end
|
@@ -193,6 +198,7 @@ module Sidekiq
|
|
193
198
|
queue class args retry_count retried_at failed_at
|
194
199
|
jid error_message error_class backtrace
|
195
200
|
error_backtrace enqueued_at retry wrapped
|
201
|
+
created_at
|
196
202
|
))
|
197
203
|
|
198
204
|
def retry_extra_items(retry_job)
|
data/lib/sidekiq/worker.rb
CHANGED
@@ -54,6 +54,8 @@ module Sidekiq
|
|
54
54
|
client_push('class' => self, 'args' => args)
|
55
55
|
end
|
56
56
|
|
57
|
+
# +interval+ must be a timestamp, numeric or something that acts
|
58
|
+
# numeric (like an activesupport time interval).
|
57
59
|
def perform_in(interval, *args)
|
58
60
|
int = interval.to_f
|
59
61
|
now = Time.now
|
data/sidekiq.gemspec
CHANGED
@@ -17,7 +17,6 @@ Gem::Specification.new do |gem|
|
|
17
17
|
gem.version = Sidekiq::VERSION
|
18
18
|
gem.add_dependency 'redis', '~> 3.2', '>= 3.2.1'
|
19
19
|
gem.add_dependency 'connection_pool', '~> 2.2', '>= 2.2.0'
|
20
|
-
gem.add_dependency 'json', '~> 1.0'
|
21
20
|
gem.add_dependency 'concurrent-ruby', '~> 1.0'
|
22
21
|
gem.add_development_dependency 'redis-namespace', '~> 1.5', '>= 1.5.2'
|
23
22
|
gem.add_development_dependency 'sinatra', '~> 1.4', '>= 1.4.6'
|
data/test/test_api.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
require_relative 'helper'
|
2
2
|
require 'sidekiq/api'
|
3
|
+
require 'active_job'
|
4
|
+
require 'action_mailer'
|
3
5
|
|
4
6
|
class TestApi < Sidekiq::Test
|
5
7
|
describe 'api' do
|
@@ -168,6 +170,21 @@ class TestApi < Sidekiq::Test
|
|
168
170
|
assert_equal 0, q.latency
|
169
171
|
end
|
170
172
|
|
173
|
+
before do
|
174
|
+
ActiveJob::Base.queue_adapter = :sidekiq
|
175
|
+
ActiveJob::Base.logger = nil
|
176
|
+
|
177
|
+
class ApiMailer < ActionMailer::Base
|
178
|
+
def test_email(*)
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
182
|
+
class ApiJob < ActiveJob::Base
|
183
|
+
def perform(*)
|
184
|
+
end
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
171
188
|
class ApiWorker
|
172
189
|
include Sidekiq::Worker
|
173
190
|
end
|
@@ -203,6 +220,22 @@ class TestApi < Sidekiq::Test
|
|
203
220
|
assert_equal [1,2,3], x.display_args
|
204
221
|
end
|
205
222
|
|
223
|
+
it 'unwraps ActiveJob jobs' do
|
224
|
+
ApiJob.perform_later(1, 2, 3)
|
225
|
+
q = Sidekiq::Queue.new
|
226
|
+
x = q.first
|
227
|
+
assert_equal "TestApi::ApiJob", x.display_class
|
228
|
+
assert_equal [1,2,3], x.display_args
|
229
|
+
end
|
230
|
+
|
231
|
+
it 'unwraps ActionMailer jobs' do
|
232
|
+
ApiMailer.test_email(1, 2, 3).deliver_later
|
233
|
+
q = Sidekiq::Queue.new('mailers')
|
234
|
+
x = q.first
|
235
|
+
assert_equal "TestApi::ApiMailer#test_email", x.display_class
|
236
|
+
assert_equal [1,2,3], x.display_args
|
237
|
+
end
|
238
|
+
|
206
239
|
it 'has no enqueued_at time for jobs enqueued in the future' do
|
207
240
|
job_id = ApiWorker.perform_in(100, 1, 'foo')
|
208
241
|
job = Sidekiq::ScheduledSet.new.find_job(job_id)
|
data/test/test_testing_fake.rb
CHANGED
@@ -54,6 +54,7 @@ class TestTesting < Sidekiq::Test
|
|
54
54
|
|
55
55
|
after do
|
56
56
|
Sidekiq::Testing.disable!
|
57
|
+
Sidekiq::Queues.clear_all
|
57
58
|
end
|
58
59
|
|
59
60
|
it 'stubs the async call' do
|
@@ -93,7 +94,7 @@ class TestTesting < Sidekiq::Test
|
|
93
94
|
it 'stubs the enqueue_to call' do
|
94
95
|
assert_equal 0, EnqueuedWorker.jobs.size
|
95
96
|
assert Sidekiq::Client.enqueue_to('someq', EnqueuedWorker, 1, 2)
|
96
|
-
assert_equal 1,
|
97
|
+
assert_equal 1, Sidekiq::Queues['someq'].size
|
97
98
|
end
|
98
99
|
|
99
100
|
it 'executes all stored jobs' do
|
@@ -263,6 +264,83 @@ class TestTesting < Sidekiq::Test
|
|
263
264
|
it 'can execute a job' do
|
264
265
|
DirectWorker.execute_job(DirectWorker.new, [2, 3])
|
265
266
|
end
|
267
|
+
end
|
268
|
+
|
269
|
+
describe 'queue testing' do
|
270
|
+
before do
|
271
|
+
require 'sidekiq/testing'
|
272
|
+
Sidekiq::Testing.fake!
|
273
|
+
end
|
266
274
|
|
275
|
+
after do
|
276
|
+
Sidekiq::Testing.disable!
|
277
|
+
Sidekiq::Queues.clear_all
|
278
|
+
end
|
279
|
+
|
280
|
+
class QueueWorker
|
281
|
+
include Sidekiq::Worker
|
282
|
+
def perform(a, b)
|
283
|
+
a + b
|
284
|
+
end
|
285
|
+
end
|
286
|
+
|
287
|
+
class AltQueueWorker
|
288
|
+
include Sidekiq::Worker
|
289
|
+
sidekiq_options queue: :alt
|
290
|
+
def perform(a, b)
|
291
|
+
a + b
|
292
|
+
end
|
293
|
+
end
|
294
|
+
|
295
|
+
it 'finds enqueued jobs' do
|
296
|
+
assert_equal 0, Sidekiq::Queues["default"].size
|
297
|
+
|
298
|
+
QueueWorker.perform_async(1, 2)
|
299
|
+
QueueWorker.perform_async(1, 2)
|
300
|
+
AltQueueWorker.perform_async(1, 2)
|
301
|
+
|
302
|
+
assert_equal 2, Sidekiq::Queues["default"].size
|
303
|
+
assert_equal [1, 2], Sidekiq::Queues["default"].first["args"]
|
304
|
+
|
305
|
+
assert_equal 1, Sidekiq::Queues["alt"].size
|
306
|
+
end
|
307
|
+
|
308
|
+
it 'clears out all queues' do
|
309
|
+
assert_equal 0, Sidekiq::Queues["default"].size
|
310
|
+
|
311
|
+
QueueWorker.perform_async(1, 2)
|
312
|
+
QueueWorker.perform_async(1, 2)
|
313
|
+
AltQueueWorker.perform_async(1, 2)
|
314
|
+
|
315
|
+
Sidekiq::Queues.clear_all
|
316
|
+
|
317
|
+
assert_equal 0, Sidekiq::Queues["default"].size
|
318
|
+
assert_equal 0, QueueWorker.jobs.size
|
319
|
+
assert_equal 0, Sidekiq::Queues["alt"].size
|
320
|
+
assert_equal 0, AltQueueWorker.jobs.size
|
321
|
+
end
|
322
|
+
|
323
|
+
it 'finds jobs enqueued by client' do
|
324
|
+
Sidekiq::Client.push(
|
325
|
+
'class' => 'NonExistentWorker',
|
326
|
+
'queue' => 'missing',
|
327
|
+
'args' => [1]
|
328
|
+
)
|
329
|
+
|
330
|
+
assert_equal 1, Sidekiq::Queues["missing"].size
|
331
|
+
end
|
332
|
+
|
333
|
+
it 'respects underlying array changes' do
|
334
|
+
# Rspec expect change() syntax saves a reference to
|
335
|
+
# an underlying array. When the array containing jobs is
|
336
|
+
# derived, Rspec test using `change(QueueWorker.jobs, :size).by(1)`
|
337
|
+
# won't pass. This attempts to recreate that scenario
|
338
|
+
# by saving a reference to the jobs array and ensuring
|
339
|
+
# it changes properly on enqueueing
|
340
|
+
jobs = QueueWorker.jobs
|
341
|
+
assert_equal 0, jobs.size
|
342
|
+
QueueWorker.perform_async(1, 2)
|
343
|
+
assert_equal 1, jobs.size
|
344
|
+
end
|
267
345
|
end
|
268
346
|
end
|
data/test/test_web.rb
CHANGED
@@ -369,19 +369,24 @@ class TestWeb < Sidekiq::Test
|
|
369
369
|
assert_equal 200, last_response.status
|
370
370
|
end
|
371
371
|
|
372
|
-
|
373
|
-
|
374
|
-
|
372
|
+
describe 'custom locales' do
|
373
|
+
before do
|
374
|
+
Sidekiq::Web.settings.locales << File.join(File.dirname(__FILE__), "fixtures")
|
375
375
|
Sidekiq::Web.tabs['Custom Tab'] = '/custom'
|
376
376
|
Sidekiq::Web.get('/custom') do
|
377
|
+
clear_caches # ugly hack since I can't figure out how to access WebHelpers outside of this context
|
377
378
|
t('translated_text')
|
378
379
|
end
|
380
|
+
end
|
379
381
|
|
382
|
+
after do
|
383
|
+
Sidekiq::Web.tabs.delete 'Custom Tab'
|
384
|
+
Sidekiq::Web.settings.locales.pop
|
385
|
+
end
|
386
|
+
|
387
|
+
it 'can show user defined tab with custom locales' do
|
380
388
|
get '/custom'
|
381
389
|
assert_match(/Changed text/, last_response.body)
|
382
|
-
|
383
|
-
ensure
|
384
|
-
Sidekiq::Web.tabs.delete 'Custom Tab'
|
385
390
|
end
|
386
391
|
end
|
387
392
|
|
data/web/locales/en.yml
CHANGED
data/web/locales/fr.yml
CHANGED
data/web/locales/ja.yml
CHANGED
@@ -38,7 +38,7 @@ ja:
|
|
38
38
|
AreYouSure: いいですか?
|
39
39
|
DeleteAll: 全て削除
|
40
40
|
RetryAll: 全て再試行
|
41
|
-
NoRetriesFound:
|
41
|
+
NoRetriesFound: 再試行するジョブはありません
|
42
42
|
Error: エラー
|
43
43
|
ErrorClass: クラスエラー
|
44
44
|
ErrorMessage: エラーメッセージ
|
@@ -67,3 +67,12 @@ ja:
|
|
67
67
|
Thread: スレッド
|
68
68
|
Threads: スレッド
|
69
69
|
Jobs: ジョブ
|
70
|
+
Paused: 一時停止中
|
71
|
+
Stop: 停止
|
72
|
+
Quiet: 処理終了
|
73
|
+
StopAll: すべて停止
|
74
|
+
QuietAll: すべて処理終了
|
75
|
+
PollingInterval: ポーリング間隔
|
76
|
+
Plugins: プラグイン
|
77
|
+
NotYetEnqueued: キューに入っていません
|
78
|
+
CreatedAt: 作成日時
|
data/web/views/_job_info.erb
CHANGED
@@ -32,6 +32,10 @@
|
|
32
32
|
<code><%= job.jid %></code>
|
33
33
|
</td>
|
34
34
|
</tr>
|
35
|
+
<tr>
|
36
|
+
<th><%= t('CreatedAt') %></th>
|
37
|
+
<td><%= relative_time(job.created_at) %></td>
|
38
|
+
</tr>
|
35
39
|
<tr>
|
36
40
|
<th><%= t('Enqueued') %></th>
|
37
41
|
<td><%= (enqueued_at = job.enqueued_at) ? relative_time(enqueued_at) : t('NotYetEnqueued') %></td>
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sidekiq
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 4.0.
|
4
|
+
version: 4.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mike Perham
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2016-01-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: redis
|
@@ -50,20 +50,6 @@ dependencies:
|
|
50
50
|
- - ">="
|
51
51
|
- !ruby/object:Gem::Version
|
52
52
|
version: 2.2.0
|
53
|
-
- !ruby/object:Gem::Dependency
|
54
|
-
name: json
|
55
|
-
requirement: !ruby/object:Gem::Requirement
|
56
|
-
requirements:
|
57
|
-
- - "~>"
|
58
|
-
- !ruby/object:Gem::Version
|
59
|
-
version: '1.0'
|
60
|
-
type: :runtime
|
61
|
-
prerelease: false
|
62
|
-
version_requirements: !ruby/object:Gem::Requirement
|
63
|
-
requirements:
|
64
|
-
- - "~>"
|
65
|
-
- !ruby/object:Gem::Version
|
66
|
-
version: '1.0'
|
67
53
|
- !ruby/object:Gem::Dependency
|
68
54
|
name: concurrent-ruby
|
69
55
|
requirement: !ruby/object:Gem::Requirement
|
@@ -381,7 +367,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
381
367
|
version: '0'
|
382
368
|
requirements: []
|
383
369
|
rubyforge_project:
|
384
|
-
rubygems_version: 2.
|
370
|
+
rubygems_version: 2.5.1
|
385
371
|
signing_key:
|
386
372
|
specification_version: 4
|
387
373
|
summary: Simple, efficient background processing for Ruby
|