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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 624586e09bcac2fc2e2a4a809f5ba7c66e270e05
4
- data.tar.gz: dc0f6f0ba020ac0b846e89c8310918a87d4d00c1
3
+ metadata.gz: 981fa47de9add237cde6413d7e97aa70726ae757
4
+ data.tar.gz: 52151d63cf02724358c925155d8f3471f453fe75
5
5
  SHA512:
6
- metadata.gz: c707028cf7bc1549c8cf5a8410867f4709c304e9490a936490cd3c068b8449a0304a17f4855d49f2ee62f829326fc3be0063a87f86bb2af34a34ed0466e40a5b
7
- data.tar.gz: cdbaa525bcb6d18b9f265f44d568c1d64d74c328c66c1d7d30fe2818d40fb4321330f532c708a76a8cd620cb545d6c86677e79c3b23bb8b520dd0d20edd1ae96
6
+ metadata.gz: 977c16381346d0fea1968ecd4d8efd2a5b900e0a0a4e4017c21fddeb910977b716959a7d8cb6515260ee4da4f58fe645a13a75b0985663594798e2f80980dcea
7
+ data.tar.gz: 2852d63ccf3686dfa438d468fdc6593ad25cd95c2f727d0c0e71625ab0c6fa42af394826105a0b7a12d103c635ea6beff8d2fb757e2ea53ef7bfb8c8785ad6e0
@@ -4,9 +4,10 @@ cache: bundler
4
4
  services:
5
5
  - redis-server
6
6
  rvm:
7
- - 2.1
7
+ - 2.1.7
8
8
  - 2.0.0
9
- - 2.2
9
+ - 2.2.4
10
+ - 2.3.0
10
11
  - jruby
11
12
  - jruby-head
12
13
  - rbx-2
@@ -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 Ukranian locale [#2561, elrakita]
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
 
@@ -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.0.pre1
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.
@@ -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.pre2
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
- At the same time, Sidekiq uses multithreading so it is much more memory efficient than
22
- Resque (which forks a new process for every job). You'll find that you might need
23
- 10 200MB resque processes to peg your CPU whereas one 300MB Sidekiq process will peg
24
- the same CPU and perform the same amount of work.
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 MRI (2.2, 2.1 and 2.0) and JRuby versions (1.7). Other versions/VMs
31
- are untested but might work fine. MRI 1.9 is no longer supported.
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 starting from 3.2 are officially supported.
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
@@ -3,7 +3,6 @@
3
3
  # Quiet some warnings we see when running in warning mode:
4
4
  # RUBYOPT=-w bundle exec sidekiq
5
5
  $TESTING = false
6
- $CELLULOID_DEBUG = false
7
6
 
8
7
  require_relative '../lib/sidekiq/cli'
9
8
 
@@ -1,6 +1,6 @@
1
1
  require 'rails_helper'
2
2
  <% module_namespacing do -%>
3
- RSpec.describe <%= class_name %>Worker, :type => :worker do
3
+ RSpec.describe <%= class_name %>Worker, type: :worker do
4
4
  pending "add some examples to (or delete) #{__FILE__}"
5
5
  end
6
- <% end -%>
6
+ <% end -%>
@@ -1,8 +1,8 @@
1
1
  require_relative 'test_helper'
2
2
  <% module_namespacing do -%>
3
- class <%= class_name %>WorkerTest < MiniTest::Unit::TestCase
4
- def test_example
5
- skip "add some examples to (or delete) #{__FILE__}"
6
- end
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 -%>
@@ -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
@@ -12,7 +12,7 @@ module Sidekiq
12
12
  end
13
13
 
14
14
  def queue_name
15
- queue.gsub(/.*queue:/, ''.freeze)
15
+ queue.sub(/.*queue:/, ''.freeze)
16
16
  end
17
17
 
18
18
  def requeue
@@ -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 0.5
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 > 0.5
72
+ while remaining > PAUSE_TIME
71
73
  return if @workers.empty?
72
- sleep 0.5
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 { "start" }
10
+ logger.info("start".freeze)
11
11
  yield
12
- logger.info { "done: #{elapsed(start)} sec" }
12
+ logger.info("done: #{elapsed(start)} sec")
13
13
  rescue Exception
14
- logger.info { "fail: #{elapsed(start)} sec" }
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..10_000]
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!
@@ -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'].constantize.jobs << Sidekiq.load_json(Sidekiq.dump_json(job))
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
- klass.jobs.unshift Sidekiq.load_json(Sidekiq.dump_json(job))
79
- klass.perform_one
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
- Worker.jobs[self]
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
- jobs.clear
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 job = jobs.shift do
159
- process_job(job)
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
- job = jobs.shift
167
- process_job(job)
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
- @jobs ||= Hash.new { |hash, key| hash[key] = [] }
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
- jobs.clear
300
+ Queues.clear_all
192
301
  end
193
302
 
194
303
  # Drain all queued jobs across all workers
195
304
  def drain_all
196
- until jobs.values.all?(&:empty?) do
197
- jobs.keys.each(&:drain)
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
@@ -1,3 +1,3 @@
1
1
  module Sidekiq
2
- VERSION = "4.0.1"
2
+ VERSION = "4.0.2"
3
3
  end
@@ -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" }
@@ -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 = settings.locales.flat_map do |path|
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)
@@ -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
@@ -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'
@@ -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)
@@ -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, EnqueuedWorker.jobs.size
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
@@ -369,19 +369,24 @@ class TestWeb < Sidekiq::Test
369
369
  assert_equal 200, last_response.status
370
370
  end
371
371
 
372
- Sidekiq::Web.settings.locales << File.join(File.dirname(__FILE__), "fixtures")
373
- it 'can show user defined tab with custom locales' do
374
- begin
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
 
@@ -75,3 +75,4 @@ en: # <---- change this to your locale code
75
75
  PollingInterval: Polling interval
76
76
  Plugins: Plugins
77
77
  NotYetEnqueued: Not yet enqueued
78
+ CreatedAt: Created At
@@ -64,6 +64,6 @@ fr:
64
64
  NoDeadJobsFound: Aucune tâche morte n'a été trouvée
65
65
  Dead: Morte
66
66
  Processes: Processus
67
- Thread: Fil
68
- Threads: Fils
67
+ Thread: Thread
68
+ Threads: Threads
69
69
  Jobs: Tâches
@@ -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: 作成日時
@@ -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.1
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: 2015-11-17 00:00:00.000000000 Z
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.4.5
370
+ rubygems_version: 2.5.1
385
371
  signing_key:
386
372
  specification_version: 4
387
373
  summary: Simple, efficient background processing for Ruby