sidekiq 3.3.0 → 3.3.1

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.

Files changed (56) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +7 -9
  3. data/Changes.md +16 -0
  4. data/Pro-2.0-Upgrade.md +102 -0
  5. data/Pro-Changes.md +14 -0
  6. data/README.md +3 -3
  7. data/Rakefile +0 -1
  8. data/bin/sidekiqctl +16 -14
  9. data/lib/sidekiq.rb +14 -14
  10. data/lib/sidekiq/api.rb +110 -40
  11. data/lib/sidekiq/cli.rb +11 -11
  12. data/lib/sidekiq/client.rb +13 -14
  13. data/lib/sidekiq/extensions/action_mailer.rb +5 -1
  14. data/lib/sidekiq/launcher.rb +4 -1
  15. data/lib/sidekiq/logging.rb +8 -7
  16. data/lib/sidekiq/manager.rb +9 -2
  17. data/lib/sidekiq/middleware/server/logging.rb +1 -1
  18. data/lib/sidekiq/middleware/server/retry_jobs.rb +4 -4
  19. data/lib/sidekiq/processor.rb +6 -6
  20. data/lib/sidekiq/testing.rb +8 -9
  21. data/lib/sidekiq/util.rb +8 -3
  22. data/lib/sidekiq/version.rb +1 -1
  23. data/lib/sidekiq/web.rb +33 -20
  24. data/lib/sidekiq/web_helpers.rb +13 -9
  25. data/lib/sidekiq/worker.rb +1 -2
  26. data/sidekiq.gemspec +1 -1
  27. data/test/test_api.rb +19 -10
  28. data/test/test_cli.rb +1 -1
  29. data/test/test_client.rb +1 -1
  30. data/test/test_exception_handler.rb +1 -1
  31. data/test/test_extensions.rb +1 -1
  32. data/test/test_fetch.rb +1 -1
  33. data/test/test_logging.rb +34 -0
  34. data/test/test_manager.rb +2 -2
  35. data/test/test_middleware.rb +1 -1
  36. data/test/test_processor.rb +1 -1
  37. data/test/test_redis_connection.rb +1 -1
  38. data/test/test_retry.rb +4 -2
  39. data/test/test_scheduled.rb +1 -1
  40. data/test/test_scheduling.rb +1 -1
  41. data/test/test_sidekiq.rb +13 -1
  42. data/test/test_testing.rb +1 -1
  43. data/test/test_testing_fake.rb +1 -1
  44. data/test/test_testing_inline.rb +1 -1
  45. data/test/test_web.rb +52 -9
  46. data/test/test_worker_generator.rb +1 -1
  47. data/web/assets/javascripts/locales/jquery.timeago.uz.js +0 -0
  48. data/web/assets/javascripts/locales/{jquery.timeago.zh-CN.js → jquery.timeago.zh-cn.js} +0 -0
  49. data/web/assets/javascripts/locales/{jquery.timeago.zh-TW.js → jquery.timeago.zh-tw.js} +0 -0
  50. data/web/assets/stylesheets/application.css +1 -4
  51. data/web/locales/ru.yml +6 -0
  52. data/web/views/_footer.erb +1 -1
  53. data/web/views/_summary.erb +1 -1
  54. data/web/views/busy.erb +3 -4
  55. data/web/views/dashboard.erb +1 -1
  56. metadata +10 -7
@@ -38,14 +38,14 @@ module Sidekiq
38
38
  end
39
39
  end
40
40
 
41
- def workers_size
42
- @workers_size ||= workers.size
43
- end
44
-
45
41
  def workers
46
42
  @workers ||= Sidekiq::Workers.new
47
43
  end
48
44
 
45
+ def processes
46
+ @processes ||= Sidekiq::ProcessSet.new
47
+ end
48
+
49
49
  def stats
50
50
  @stats ||= Sidekiq::Stats.new
51
51
  end
@@ -65,7 +65,7 @@ module Sidekiq
65
65
  end
66
66
 
67
67
  def namespace
68
- @@ns ||= Sidekiq.redis {|conn| conn.respond_to?(:namespace) ? conn.namespace : nil }
68
+ @@ns ||= Sidekiq.redis { |conn| conn.respond_to?(:namespace) ? conn.namespace : nil }
69
69
  end
70
70
 
71
71
  def redis_info
@@ -89,7 +89,7 @@ module Sidekiq
89
89
  end
90
90
 
91
91
  def current_status
92
- workers_size == 0 ? 'idle' : 'active'
92
+ workers.size == 0 ? 'idle' : 'active'
93
93
  end
94
94
 
95
95
  def relative_time(time)
@@ -110,9 +110,9 @@ module Sidekiq
110
110
  # Merge options with current params, filter safe params, and stringify to query string
111
111
  def qparams(options)
112
112
  options = options.stringify_keys
113
- params.merge(options).map { |key, value|
113
+ params.merge(options).map do |key, value|
114
114
  SAFE_QPARAMS.include?(key) ? "#{key}=#{value}" : next
115
- }.join("&")
115
+ end.join("&")
116
116
  end
117
117
 
118
118
  def truncate(text, truncate_after_chars = 2000)
@@ -147,7 +147,7 @@ module Sidekiq
147
147
  return number
148
148
  end
149
149
 
150
- options = {:delimiter => ',', :separator => '.'}
150
+ options = {delimiter: ',', separator: '.'}
151
151
  parts = number.to_s.to_str.split('.')
152
152
  parts[0].gsub!(/(\d)(?=(\d\d\d)+(?!\d))/, "\\1#{options[:delimiter]}")
153
153
  parts.join(options[:separator])
@@ -178,5 +178,9 @@ module Sidekiq
178
178
 
179
179
  "[#{environment.upcase}] " unless environment == "production"
180
180
  end
181
+
182
+ def product_version
183
+ "Sidekiq v#{Sidekiq::VERSION}"
184
+ end
181
185
  end
182
186
  end
@@ -48,7 +48,7 @@ module Sidekiq
48
48
  item = { 'class' => self, 'args' => args, 'at' => ts }
49
49
 
50
50
  # Optimization to enqueue something now that is scheduled to go out now or in the past
51
- item.delete('at') if ts <= now
51
+ item.delete('at'.freeze) if ts <= now
52
52
 
53
53
  client_push(item)
54
54
  end
@@ -65,7 +65,6 @@ module Sidekiq
65
65
  # :pool - use the given Redis connection pool to push this type of job to a given shard.
66
66
  def sidekiq_options(opts={})
67
67
  self.sidekiq_options_hash = get_sidekiq_options.merge((opts || {}).stringify_keys)
68
- ::Sidekiq.logger.warn("#{self.name} - :timeout is unsafe and support has been removed from Sidekiq, see http://bit.ly/OtYpK for details") if opts.include? :timeout
69
68
  end
70
69
 
71
70
  def sidekiq_retry_in(&block)
@@ -16,7 +16,7 @@ Gem::Specification.new do |gem|
16
16
  gem.version = Sidekiq::VERSION
17
17
  gem.add_dependency 'redis', '>= 3.0.6'
18
18
  gem.add_dependency 'redis-namespace', '>= 1.3.1'
19
- gem.add_dependency 'connection_pool', '>= 2.0.0'
19
+ gem.add_dependency 'connection_pool', '>= 2.1.1'
20
20
  gem.add_dependency 'celluloid', '>= 0.16.0'
21
21
  gem.add_dependency 'json'
22
22
  gem.add_development_dependency 'sinatra'
@@ -1,4 +1,4 @@
1
- require 'helper'
1
+ require_relative 'helper'
2
2
 
3
3
  class TestApi < Sidekiq::Test
4
4
 
@@ -77,8 +77,8 @@ class TestApi < Sidekiq::Test
77
77
 
78
78
  describe "queues" do
79
79
  it "is initially empty" do
80
- s = Sidekiq::Stats.new
81
- assert_equal 0, s.queues.size
80
+ s = Sidekiq::Stats::Queues.new
81
+ assert_equal 0, s.lengths.size
82
82
  end
83
83
 
84
84
  it "returns a hash of queue and size in order" do
@@ -90,9 +90,9 @@ class TestApi < Sidekiq::Test
90
90
  conn.sadd 'queues', 'bar'
91
91
  end
92
92
 
93
- s = Sidekiq::Stats.new
94
- assert_equal ({ "foo" => 1, "bar" => 3 }), s.queues
95
- assert_equal "bar", s.queues.first.first
93
+ s = Sidekiq::Stats::Queues.new
94
+ assert_equal ({ "foo" => 1, "bar" => 3 }), s.lengths
95
+ assert_equal "bar", s.lengths.first.first
96
96
  end
97
97
  end
98
98
 
@@ -252,7 +252,7 @@ class TestApi < Sidekiq::Test
252
252
  job = Sidekiq::ScheduledSet.new.find_job(job_id)
253
253
  refute_nil job
254
254
  assert_equal job_id, job.jid
255
- assert_in_delta job.latency, 0.0, 0.01
255
+ assert_in_delta job.latency, 0.0, 0.1
256
256
  end
257
257
 
258
258
  it 'can remove jobs when iterating over a sorted set' do
@@ -374,7 +374,15 @@ class TestApi < Sidekiq::Test
374
374
  end
375
375
 
376
376
  it 'can enumerate processes' do
377
- odata = { 'pid' => 123, 'hostname' => hostname, 'key' => "#{hostname}:123", 'started_at' => Time.now.to_f - 15 }
377
+ identity_string = "identity_string"
378
+ odata = {
379
+ 'pid' => 123,
380
+ 'hostname' => hostname,
381
+ 'key' => identity_string,
382
+ 'identity' => identity_string,
383
+ 'started_at' => Time.now.to_f - 15,
384
+ }
385
+
378
386
  time = Time.now.to_f
379
387
  Sidekiq.redis do |conn|
380
388
  conn.multi do
@@ -392,8 +400,9 @@ class TestApi < Sidekiq::Test
392
400
  assert_equal 123, data['pid']
393
401
  data.quiet!
394
402
  data.stop!
395
- assert_equal "TERM", Sidekiq.redis{|c| c.lpop("#{hostname}:123-signals") }
396
- assert_equal "USR1", Sidekiq.redis{|c| c.lpop("#{hostname}:123-signals") }
403
+ signals_string = "#{odata['key']}-signals"
404
+ assert_equal "TERM", Sidekiq.redis{|c| c.lpop(signals_string) }
405
+ assert_equal "USR1", Sidekiq.redis{|c| c.lpop(signals_string) }
397
406
  end
398
407
 
399
408
  it 'can enumerate workers' do
@@ -1,4 +1,4 @@
1
- require 'helper'
1
+ require_relative 'helper'
2
2
  require 'sidekiq/cli'
3
3
  require 'tempfile'
4
4
 
@@ -1,4 +1,4 @@
1
- require 'helper'
1
+ require_relative 'helper'
2
2
  require 'sidekiq/client'
3
3
  require 'sidekiq/worker'
4
4
 
@@ -1,4 +1,4 @@
1
- require 'helper'
1
+ require_relative 'helper'
2
2
  require 'sidekiq/exception_handler'
3
3
  require 'stringio'
4
4
  require 'logger'
@@ -1,4 +1,4 @@
1
- require 'helper'
1
+ require_relative 'helper'
2
2
  require 'sidekiq'
3
3
  require 'active_record'
4
4
  require 'action_mailer'
@@ -1,4 +1,4 @@
1
- require 'helper'
1
+ require_relative 'helper'
2
2
  require 'sidekiq/fetch'
3
3
 
4
4
  class TestFetcher < Sidekiq::Test
@@ -0,0 +1,34 @@
1
+ require_relative 'helper'
2
+ require 'sidekiq/logging'
3
+
4
+ class TestFetcher < Sidekiq::Test
5
+ describe Sidekiq::Logging do
6
+ describe "#with_context" do
7
+ def context
8
+ Sidekiq::Logging.logger.formatter.context
9
+ end
10
+
11
+ it "has no context by default" do
12
+ context.must_equal nil
13
+ end
14
+
15
+ it "can add a context" do
16
+ Sidekiq::Logging.with_context "xx" do
17
+ context.must_equal " xx"
18
+ end
19
+ context.must_equal nil
20
+ end
21
+
22
+ it "can use multiple contexts" do
23
+ Sidekiq::Logging.with_context "xx" do
24
+ context.must_equal " xx"
25
+ Sidekiq::Logging.with_context "yy" do
26
+ context.must_equal " xx yy"
27
+ end
28
+ context.must_equal " xx"
29
+ end
30
+ context.must_equal nil
31
+ end
32
+ end
33
+ end
34
+ end
@@ -1,4 +1,4 @@
1
- require 'helper'
1
+ require_relative 'helper'
2
2
  require 'sidekiq/manager'
3
3
 
4
4
  class TestManager < Sidekiq::Test
@@ -121,7 +121,7 @@ class TestManager < Sidekiq::Test
121
121
  info = Sidekiq.redis { |c| c.hmget('identity', 'busy') }
122
122
  assert_equal ["1"], info
123
123
  expires = Sidekiq.redis { |c| c.pttl('identity') }
124
- assert_in_delta 60000, expires, 10
124
+ assert_in_delta 60000, expires, 500
125
125
  end
126
126
  end
127
127
 
@@ -1,4 +1,4 @@
1
- require 'helper'
1
+ require_relative 'helper'
2
2
  require 'sidekiq/middleware/chain'
3
3
  require 'sidekiq/processor'
4
4
 
@@ -1,4 +1,4 @@
1
- require 'helper'
1
+ require_relative 'helper'
2
2
  require 'sidekiq/processor'
3
3
 
4
4
  class TestProcessor < Sidekiq::Test
@@ -1,4 +1,4 @@
1
- require 'helper'
1
+ require_relative 'helper'
2
2
  require 'sidekiq/redis_connection'
3
3
 
4
4
  class TestRedisConnection < Sidekiq::Test
@@ -1,5 +1,5 @@
1
1
  # encoding: utf-8
2
- require 'helper'
2
+ require_relative 'helper'
3
3
  require 'sidekiq/scheduled'
4
4
  require 'sidekiq/middleware/server/retry_jobs'
5
5
 
@@ -110,11 +110,13 @@ class TestRetry < Sidekiq::Test
110
110
  c = nil
111
111
  assert_raises RuntimeError do
112
112
  handler.call(worker, msg, 'default') do
113
- c = caller(0)[0..3]; raise "kerblammo!"
113
+ c = caller(0)[0...3]; raise "kerblammo!"
114
114
  end
115
115
  end
116
116
  assert msg["error_backtrace"]
117
117
  assert_equal c, msg["error_backtrace"]
118
+ assert_equal 3, c.size
119
+ assert_equal 3, msg["error_backtrace"].size
118
120
  end
119
121
 
120
122
  it 'handles a new failed message' do
@@ -1,4 +1,4 @@
1
- require 'helper'
1
+ require_relative 'helper'
2
2
  require 'sidekiq/scheduled'
3
3
 
4
4
  class TestScheduled < Sidekiq::Test
@@ -1,4 +1,4 @@
1
- require 'helper'
1
+ require_relative 'helper'
2
2
  require 'sidekiq/scheduled'
3
3
 
4
4
  class TestScheduling < Sidekiq::Test
@@ -1,5 +1,5 @@
1
1
  # encoding: utf-8
2
- require 'helper'
2
+ require_relative 'helper'
3
3
 
4
4
  class TestSidekiq < Sidekiq::Test
5
5
  describe 'json processing' do
@@ -54,4 +54,16 @@ class TestSidekiq < Sidekiq::Test
54
54
  assert_equal 2, Sidekiq.options[:lifecycle_events][:startup].first.call
55
55
  end
56
56
  end
57
+
58
+ describe 'default_worker_options' do
59
+ before do
60
+ @old_options = Sidekiq.default_worker_options
61
+ end
62
+ after { Sidekiq.default_worker_options = @old_options }
63
+
64
+ it 'stringify keys' do
65
+ Sidekiq.default_worker_options = { queue: 'cat'}
66
+ assert_equal 'cat', Sidekiq.default_worker_options['queue']
67
+ end
68
+ end
57
69
  end
@@ -1,4 +1,4 @@
1
- require 'helper'
1
+ require_relative 'helper'
2
2
  require 'sidekiq'
3
3
  require 'sidekiq/worker'
4
4
  require 'active_record'
@@ -1,4 +1,4 @@
1
- require 'helper'
1
+ require_relative 'helper'
2
2
  require 'sidekiq'
3
3
  require 'sidekiq/worker'
4
4
  require 'active_record'
@@ -1,4 +1,4 @@
1
- require 'helper'
1
+ require_relative 'helper'
2
2
  require 'sidekiq'
3
3
  require 'sidekiq/worker'
4
4
  require 'active_record'
@@ -1,4 +1,4 @@
1
- require 'helper'
1
+ require_relative 'helper'
2
2
  require 'sidekiq'
3
3
  require 'sidekiq/web'
4
4
  require 'rack/test'
@@ -50,17 +50,23 @@ class TestWeb < Sidekiq::Test
50
50
  end
51
51
 
52
52
  it 'can quiet a process' do
53
- assert_nil Sidekiq.redis { |c| c.lpop "host:pid-signals" }
54
- post '/busy', 'quiet' => '1', 'hostname' => 'host', 'pid' => 'pid'
53
+ identity = 'identity'
54
+ signals_key = "#{identity}-signals"
55
+
56
+ assert_nil Sidekiq.redis { |c| c.lpop signals_key }
57
+ post '/busy', 'quiet' => '1', 'identity' => identity
55
58
  assert_equal 302, last_response.status
56
- assert_equal 'USR1', Sidekiq.redis { |c| c.lpop "host:pid-signals" }
59
+ assert_equal 'USR1', Sidekiq.redis { |c| c.lpop signals_key }
57
60
  end
58
61
 
59
62
  it 'can stop a process' do
60
- assert_nil Sidekiq.redis { |c| c.lpop "host:pid-signals" }
61
- post '/busy', 'stop' => '1', 'hostname' => 'host', 'pid' => 'pid'
63
+ identity = 'identity'
64
+ signals_key = "#{identity}-signals"
65
+
66
+ assert_nil Sidekiq.redis { |c| c.lpop signals_key }
67
+ post '/busy', 'stop' => '1', 'identity' => identity
62
68
  assert_equal 302, last_response.status
63
- assert_equal 'TERM', Sidekiq.redis { |c| c.lpop "host:pid-signals" }
69
+ assert_equal 'TERM', Sidekiq.redis { |c| c.lpop signals_key }
64
70
  end
65
71
  end
66
72
 
@@ -352,6 +358,14 @@ class TestWeb < Sidekiq::Test
352
358
  end
353
359
  end
354
360
 
361
+ describe 'dashboard/stats' do
362
+ it 'redirects to stats' do
363
+ get '/dashboard/stats'
364
+ assert_equal 302, last_response.status
365
+ assert_equal 'http://example.org/stats', last_response.header['Location']
366
+ end
367
+ end
368
+
355
369
  describe 'stats' do
356
370
  include Sidekiq::Util
357
371
 
@@ -359,12 +373,13 @@ class TestWeb < Sidekiq::Test
359
373
  Sidekiq.redis do |conn|
360
374
  conn.set("stat:processed", 5)
361
375
  conn.set("stat:failed", 2)
376
+ conn.sadd("queues", "default")
362
377
  end
363
378
  2.times { add_retry }
364
379
  3.times { add_scheduled }
365
380
  4.times { add_worker }
366
381
 
367
- get '/dashboard/stats'
382
+ get '/stats'
368
383
  @response = Sidekiq.load_json(last_response.body)
369
384
  end
370
385
 
@@ -389,6 +404,10 @@ class TestWeb < Sidekiq::Test
389
404
  assert_equal 4, @response["sidekiq"]["busy"]
390
405
  end
391
406
 
407
+ it 'reports processes' do
408
+ assert_equal 1, @response["sidekiq"]["processes"]
409
+ end
410
+
392
411
  it 'reports retries' do
393
412
  assert_equal 2, @response["sidekiq"]["retries"]
394
413
  end
@@ -429,6 +448,30 @@ class TestWeb < Sidekiq::Test
429
448
  end
430
449
  end
431
450
 
451
+ describe 'stats/queues' do
452
+ include Sidekiq::Util
453
+
454
+ before do
455
+ Sidekiq.redis do |conn|
456
+ conn.set("stat:processed", 5)
457
+ conn.set("stat:failed", 2)
458
+ conn.sadd("queues", "default")
459
+ conn.sadd("queues", "queue2")
460
+ end
461
+ 2.times { add_retry }
462
+ 3.times { add_scheduled }
463
+ 4.times { add_worker }
464
+
465
+ get '/stats/queues'
466
+ @response = Sidekiq.load_json(last_response.body)
467
+ end
468
+
469
+ it 'reports the queue depth' do
470
+ assert_equal 0, @response["default"]
471
+ assert_equal 0, @response["queue2"]
472
+ end
473
+ end
474
+
432
475
  describe 'dead jobs' do
433
476
  it 'shows empty index' do
434
477
  get 'morgue'
@@ -529,7 +572,7 @@ class TestWeb < Sidekiq::Test
529
572
  Sidekiq.redis do |conn|
530
573
  conn.multi do
531
574
  conn.sadd("processes", key)
532
- conn.hmset(key, 'busy', 4)
575
+ conn.hmset(key, 'info', Sidekiq.dump_json('hostname' => 'foo', 'started_at' => Time.now.to_f, "queues" => []), 'at', Time.now.to_f, 'busy', 4)
533
576
  conn.hmset("#{key}:workers", Time.now.to_f, msg)
534
577
  end
535
578
  end