sidekiq 2.2.1 → 2.3.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.

Files changed (87) hide show
  1. data/Changes.md +9 -0
  2. data/Gemfile +1 -2
  3. data/README.md +2 -2
  4. data/examples/sinkiq.rb +2 -2
  5. data/lib/sidekiq.rb +2 -0
  6. data/lib/sidekiq/cli.rb +4 -0
  7. data/lib/sidekiq/client.rb +13 -3
  8. data/lib/sidekiq/exception_handler.rb +1 -1
  9. data/lib/sidekiq/manager.rb +1 -2
  10. data/lib/sidekiq/middleware/server/logging.rb +1 -1
  11. data/lib/sidekiq/middleware/server/retry_jobs.rb +3 -3
  12. data/lib/sidekiq/processor.rb +12 -15
  13. data/lib/sidekiq/stats.rb +36 -0
  14. data/lib/sidekiq/testing/inline.rb +6 -6
  15. data/lib/sidekiq/util.rb +2 -2
  16. data/lib/sidekiq/version.rb +1 -1
  17. data/lib/sidekiq/web.rb +21 -8
  18. data/sidekiq.gemspec +3 -2
  19. data/test/helper.rb +2 -0
  20. data/test/test_client.rb +7 -0
  21. data/test/test_exception_handler.rb +1 -1
  22. data/test/test_stats.rb +47 -8
  23. data/test/test_testing.rb +7 -0
  24. data/test/test_testing_inline.rb +4 -4
  25. data/web/assets/images/bootstrap/glyphicons-halflings-white.png +0 -0
  26. data/web/assets/images/bootstrap/glyphicons-halflings.png +0 -0
  27. data/web/assets/javascripts/application.js +7 -0
  28. data/web/assets/javascripts/vendor/bootstrap.js +2027 -12
  29. data/web/assets/stylesheets/layout.css +5 -1
  30. data/web/assets/stylesheets/vendor/bootstrap-responsive.css +841 -368
  31. data/web/assets/stylesheets/vendor/bootstrap.css +3565 -1306
  32. data/web/views/_summary.slim +6 -6
  33. data/web/views/index.slim +6 -5
  34. data/web/views/layout.slim +1 -1
  35. data/web/views/queues.slim +2 -2
  36. metadata +21 -55
  37. data/myapp/.gitignore +0 -15
  38. data/myapp/Capfile +0 -5
  39. data/myapp/Gemfile +0 -19
  40. data/myapp/Rakefile +0 -7
  41. data/myapp/app/controllers/application_controller.rb +0 -3
  42. data/myapp/app/controllers/work_controller.rb +0 -38
  43. data/myapp/app/helpers/application_helper.rb +0 -2
  44. data/myapp/app/mailers/.gitkeep +0 -0
  45. data/myapp/app/mailers/user_mailer.rb +0 -9
  46. data/myapp/app/models/.gitkeep +0 -0
  47. data/myapp/app/models/post.rb +0 -5
  48. data/myapp/app/views/layouts/application.html.erb +0 -14
  49. data/myapp/app/views/user_mailer/greetings.html.erb +0 -3
  50. data/myapp/app/views/work/index.html.erb +0 -1
  51. data/myapp/app/workers/hard_worker.rb +0 -10
  52. data/myapp/config.ru +0 -4
  53. data/myapp/config/application.rb +0 -59
  54. data/myapp/config/boot.rb +0 -6
  55. data/myapp/config/database.yml +0 -25
  56. data/myapp/config/deploy.rb +0 -15
  57. data/myapp/config/environment.rb +0 -5
  58. data/myapp/config/environments/development.rb +0 -38
  59. data/myapp/config/environments/production.rb +0 -67
  60. data/myapp/config/environments/test.rb +0 -37
  61. data/myapp/config/initializers/backtrace_silencers.rb +0 -7
  62. data/myapp/config/initializers/inflections.rb +0 -15
  63. data/myapp/config/initializers/mime_types.rb +0 -5
  64. data/myapp/config/initializers/secret_token.rb +0 -7
  65. data/myapp/config/initializers/session_store.rb +0 -8
  66. data/myapp/config/initializers/sidekiq.rb +0 -6
  67. data/myapp/config/initializers/wrap_parameters.rb +0 -14
  68. data/myapp/config/locales/en.yml +0 -5
  69. data/myapp/config/routes.rb +0 -10
  70. data/myapp/db/migrate/20120123214055_create_posts.rb +0 -10
  71. data/myapp/db/seeds.rb +0 -7
  72. data/myapp/lib/assets/.gitkeep +0 -0
  73. data/myapp/lib/tasks/.gitkeep +0 -0
  74. data/myapp/log/.gitkeep +0 -0
  75. data/myapp/script/rails +0 -6
  76. data/web/assets/javascripts/vendor/bootstrap/bootstrap-alert.js +0 -91
  77. data/web/assets/javascripts/vendor/bootstrap/bootstrap-button.js +0 -98
  78. data/web/assets/javascripts/vendor/bootstrap/bootstrap-carousel.js +0 -154
  79. data/web/assets/javascripts/vendor/bootstrap/bootstrap-collapse.js +0 -136
  80. data/web/assets/javascripts/vendor/bootstrap/bootstrap-dropdown.js +0 -92
  81. data/web/assets/javascripts/vendor/bootstrap/bootstrap-modal.js +0 -210
  82. data/web/assets/javascripts/vendor/bootstrap/bootstrap-popover.js +0 -95
  83. data/web/assets/javascripts/vendor/bootstrap/bootstrap-scrollspy.js +0 -125
  84. data/web/assets/javascripts/vendor/bootstrap/bootstrap-tab.js +0 -130
  85. data/web/assets/javascripts/vendor/bootstrap/bootstrap-tooltip.js +0 -270
  86. data/web/assets/javascripts/vendor/bootstrap/bootstrap-transition.js +0 -51
  87. data/web/assets/javascripts/vendor/bootstrap/bootstrap-typeahead.js +0 -271
data/Changes.md CHANGED
@@ -1,3 +1,12 @@
1
+ 2.3.0
2
+ -----------
3
+
4
+ - Upgrade Celluloid to 0.12
5
+ - Upgrade Twitter Bootstrap to 2.1.0
6
+ - Rescue more Exceptions
7
+ - Change Job ID to be Hex, rather than Base64, for HTTP safety
8
+ - Use `Airbrake#notify_or_ignore`
9
+
1
10
  2.2.1
2
11
  -----------
3
12
 
data/Gemfile CHANGED
@@ -1,9 +1,8 @@
1
1
  source 'http://rubygems.org'
2
2
  gemspec
3
3
 
4
- gem 'celluloid'
4
+ gem 'celluloid', "~> 0.12.0"
5
5
  gem 'slim'
6
- gem 'sprockets'
7
6
  gem 'sass'
8
7
  gem 'rails', '3.2.8'
9
8
  gem 'sqlite3'
data/README.md CHANGED
@@ -7,8 +7,8 @@ Sidekiq
7
7
  Simple, efficient message processing for Ruby.
8
8
 
9
9
  Sidekiq uses threads to handle many messages at the same time in the
10
- same process. It integrates tightly with Rails 3 to make background
11
- message processing dead simple.
10
+ same process. It does not require Rails but will integrate tightly with
11
+ Rails 3 to make background message processing dead simple.
12
12
 
13
13
  Sidekiq is compatible with Resque. It uses the exact same
14
14
  message format as Resque so it can integrate into an existing Resque processing farm.
@@ -19,8 +19,8 @@ class SinatraWorker
19
19
  end
20
20
 
21
21
  get '/' do
22
- @failed = $redis.get('stat:failed')
23
- @processed = $redis.get('stat:processed')
22
+ @failed = Sidekiq::Stats.failed
23
+ @processed = Sidekiq::Stats.processed
24
24
  @messages = $redis.lrange('sinkiq-example-messages', 0, -1)
25
25
  erb :index
26
26
  end
@@ -4,6 +4,7 @@ require 'sidekiq/client'
4
4
  require 'sidekiq/worker'
5
5
  require 'sidekiq/redis_connection'
6
6
  require 'sidekiq/util'
7
+ require 'sidekiq/stats'
7
8
 
8
9
  require 'sidekiq/extensions/class_methods'
9
10
  require 'sidekiq/extensions/action_mailer'
@@ -13,6 +14,7 @@ require 'sidekiq/rails' if defined?(::Rails::Engine)
13
14
  require 'multi_json'
14
15
 
15
16
  module Sidekiq
17
+ LICENSE = 'See LICENSE and the LGPL-3.0 for licensing details.'
16
18
 
17
19
  DEFAULTS = {
18
20
  :queues => [],
@@ -66,6 +66,10 @@ module Sidekiq
66
66
  end
67
67
 
68
68
  def run
69
+ logger.info "Booting Sidekiq #{Sidekiq::VERSION} with Redis at #{redis {|x| x.client.id}}"
70
+ logger.info "Running in #{RUBY_DESCRIPTION}"
71
+ logger.info Sidekiq::LICENSE
72
+
69
73
  @manager = Sidekiq::Manager.new(options)
70
74
  poller = Sidekiq::Scheduled::Poller.new
71
75
  begin
@@ -1,3 +1,5 @@
1
+ require 'securerandom'
2
+
1
3
  require 'sidekiq/middleware/chain'
2
4
 
3
5
  module Sidekiq
@@ -44,7 +46,7 @@ module Sidekiq
44
46
  item = worker_class.get_sidekiq_options.merge(item)
45
47
  item['retry'] = !!item['retry']
46
48
  queue = item['queue']
47
- item['jid'] = SecureRandom.base64
49
+ item['jid'] = SecureRandom.hex(12)
48
50
 
49
51
  pushed = false
50
52
  Sidekiq.client_middleware.invoke(worker_class, item, queue) do
@@ -63,14 +65,22 @@ module Sidekiq
63
65
  pushed ? item['jid'] : nil
64
66
  end
65
67
 
66
- # Redis compatibility helper. Example usage:
68
+ # Resque compatibility helpers.
67
69
  #
70
+ # Example usage:
68
71
  # Sidekiq::Client.enqueue(MyWorker, 'foo', 1, :bat => 'bar')
69
72
  #
70
73
  # Messages are enqueued to the 'default' queue.
71
74
  #
72
75
  def self.enqueue(klass, *args)
73
- klass.perform_async(*args)
76
+ klass.client_push('class' => klass, 'args' => args)
77
+ end
78
+
79
+ # Example usage:
80
+ # Sidekiq::Client.enqueue_to(:queue_name, MyWorker, 'foo', 1, :bat => 'bar')
81
+ #
82
+ def self.enqueue_to(queue, klass, *args)
83
+ klass.client_push('queue' => queue, 'class' => klass, 'args' => args)
74
84
  end
75
85
  end
76
86
  end
@@ -13,7 +13,7 @@ module Sidekiq
13
13
  private
14
14
 
15
15
  def send_to_airbrake(msg, ex)
16
- ::Airbrake.notify(ex, :parameters => msg)
16
+ ::Airbrake.notify_or_ignore(ex, :parameters => msg)
17
17
  end
18
18
 
19
19
  def send_to_exceptional(msg, ex)
@@ -18,8 +18,6 @@ module Sidekiq
18
18
  trap_exit :processor_died
19
19
 
20
20
  def initialize(options={})
21
- logger.info "Booting sidekiq #{Sidekiq::VERSION} with Redis at #{redis {|x| x.client.id}}"
22
- logger.info "Running in #{RUBY_DESCRIPTION}"
23
21
  logger.debug { options.inspect }
24
22
  @count = options[:concurrency] || 25
25
23
  @done_callback = nil
@@ -129,6 +127,7 @@ module Sidekiq
129
127
  # processor is an actor proxy and we can't call any methods
130
128
  # that would go to the actor (since it's busy). Instead
131
129
  # we'll use the object_id to track the worker's data here.
130
+ processor.terminate if processor.alive?
132
131
  msg, queue = @in_progress[processor.object_id]
133
132
  conn.lpush("queue:#{queue}", msg)
134
133
  end
@@ -10,7 +10,7 @@ module Sidekiq
10
10
  logger.info { "start" }
11
11
  yield
12
12
  logger.info { "done: #{elapsed(start)} sec" }
13
- rescue
13
+ rescue Exception
14
14
  logger.info { "fail: #{elapsed(start)} sec" }
15
15
  raise
16
16
  end
@@ -40,8 +40,8 @@ module Sidekiq
40
40
 
41
41
  def call(worker, msg, queue)
42
42
  yield
43
- rescue => e
44
- raise unless msg['retry']
43
+ rescue Exception => e
44
+ raise e unless msg['retry']
45
45
 
46
46
  msg['queue'] = queue
47
47
  msg['error_message'] = e.message
@@ -72,7 +72,7 @@ module Sidekiq
72
72
  # Goodbye dear message, you (re)tried your best I'm sure.
73
73
  logger.debug { "Dropping message after hitting the retry maximum: #{msg}" }
74
74
  end
75
- raise
75
+ raise e
76
76
  end
77
77
 
78
78
  end
@@ -15,6 +15,8 @@ module Sidekiq
15
15
  include Util
16
16
  include Celluloid
17
17
 
18
+ # exclusive :process
19
+
18
20
  def self.default_middleware
19
21
  Middleware::Chain.new do |m|
20
22
  m.add Middleware::Server::Logging
@@ -29,24 +31,19 @@ module Sidekiq
29
31
  end
30
32
 
31
33
  def process(msgstr, queue)
32
- # Defer worker execution to Celluloid's thread pool since all actor
33
- # invocations are run within a Fiber, which dramatically limits
34
- # our stack size.
35
- defer do
36
- begin
37
- msg = Sidekiq.load_json(msgstr)
38
- klass = constantize(msg['class'])
39
- worker = klass.new
34
+ begin
35
+ msg = Sidekiq.load_json(msgstr)
36
+ klass = constantize(msg['class'])
37
+ worker = klass.new
40
38
 
41
- stats(worker, msg, queue) do
42
- Sidekiq.server_middleware.invoke(worker, msg, queue) do
43
- worker.perform(*cloned(msg['args']))
44
- end
39
+ stats(worker, msg, queue) do
40
+ Sidekiq.server_middleware.invoke(worker, msg, queue) do
41
+ worker.perform(*cloned(msg['args']))
45
42
  end
46
- rescue Exception => ex
47
- handle_exception(ex, msg || { :message => msgstr })
48
- raise
49
43
  end
44
+ rescue Exception => ex
45
+ handle_exception(ex, msg || { :message => msgstr })
46
+ raise
50
47
  end
51
48
  @boss.processor_done!(current_actor)
52
49
  end
@@ -0,0 +1,36 @@
1
+ module Sidekiq
2
+ module_function
3
+
4
+ def info
5
+ results = {}
6
+ processed, failed, queues = Sidekiq.redis { |conn|
7
+ conn.multi do
8
+ conn.get('stat:processed')
9
+ conn.get('stat:failed')
10
+ conn.smembers('queues')
11
+ end
12
+ }
13
+ results[:queues_with_sizes] = Sidekiq.redis do |conn|
14
+ queues.inject({}) { |memo, q|
15
+ memo[q] = conn.llen("queue:#{q}")
16
+ memo
17
+ }.sort_by { |_, size| size }
18
+ end
19
+ results[:processed] = (processed || 0).to_i
20
+ results[:failed] = (failed || 0).to_i
21
+ results[:backlog] = results[:queues_with_sizes].
22
+ map {|_, size| size }.
23
+ inject(0) {|memo, val| memo + val }
24
+ results
25
+ end
26
+
27
+ def size(*queues)
28
+ return info[:backlog] if queues.empty?
29
+
30
+ Sidekiq.redis { |conn|
31
+ conn.multi {
32
+ queues.map { |q| conn.llen("queue:#{q}") }
33
+ }
34
+ }.inject(0) { |memo, count| memo += count }
35
+ end
36
+ end
@@ -1,8 +1,8 @@
1
1
  module Sidekiq
2
- module Worker
2
+ class Client
3
3
 
4
4
  ##
5
- # The Sidekiq inline infrastructure overrides the perform_async so that it
5
+ # The Sidekiq inline infrastructure overrides perform_async so that it
6
6
  # actually calls perform instead. This allows workers to be run inline in a
7
7
  # testing environment.
8
8
  #
@@ -26,10 +26,10 @@ module Sidekiq
26
26
  # ExternalWorker.perform_async
27
27
  # assert_equal 1, $external_variable
28
28
  #
29
- module ClassMethods
30
- alias_method :perform_async_old, :perform_async
31
- def perform_async(*args)
32
- new.perform(*Sidekiq.load_json(Sidekiq.dump_json(args)))
29
+ singleton_class.class_eval do
30
+ alias_method :push_old, :push
31
+ def push(hash)
32
+ hash['class'].new.perform(*Sidekiq.load_json(Sidekiq.dump_json(hash['args'])))
33
33
  true
34
34
  end
35
35
  end
@@ -7,7 +7,7 @@ module Sidekiq
7
7
  module Util
8
8
  include ExceptionHandler
9
9
 
10
- EXPIRY = 60 * 60
10
+ EXPIRY = 60 * 60 * 24
11
11
 
12
12
  def constantize(camel_cased_word)
13
13
  names = camel_cased_word.split('::')
@@ -22,7 +22,7 @@ module Sidekiq
22
22
 
23
23
  def watchdog(last_words)
24
24
  yield
25
- rescue => ex
25
+ rescue Exception => ex
26
26
  handle_exception(ex, { :context => last_words })
27
27
  end
28
28
 
@@ -1,3 +1,3 @@
1
1
  module Sidekiq
2
- VERSION = "2.2.1"
2
+ VERSION = "2.3.0"
3
3
  end
@@ -60,12 +60,16 @@ module Sidekiq
60
60
  end
61
61
  end
62
62
 
63
+ def info
64
+ @info ||= Sidekiq.info
65
+ end
66
+
63
67
  def processed
64
- Sidekiq.redis { |conn| conn.get('stat:processed') } || 0
68
+ info[:processed]
65
69
  end
66
70
 
67
71
  def failed
68
- Sidekiq.redis { |conn| conn.get('stat:failed') } || 0
72
+ info[:failed]
69
73
  end
70
74
 
71
75
  def zcard(name)
@@ -73,15 +77,11 @@ module Sidekiq
73
77
  end
74
78
 
75
79
  def queues
76
- @queues ||= Sidekiq.redis do |conn|
77
- conn.smembers('queues').map do |q|
78
- [q, conn.llen("queue:#{q}") || 0]
79
- end.sort { |x,y| x[1] <=> y[1] }
80
- end
80
+ @queues ||= Sidekiq.info[:queues_with_sizes]
81
81
  end
82
82
 
83
83
  def backlog
84
- queues.map {|name, size| size }.inject(0) {|memo, val| memo + val }
84
+ info[:backlog]
85
85
  end
86
86
 
87
87
  def retries_with_score(score)
@@ -115,6 +115,19 @@ module Sidekiq
115
115
  def tabs
116
116
  self.class.tabs
117
117
  end
118
+
119
+ def number_with_delimiter(number)
120
+ begin
121
+ Float(number)
122
+ rescue ArgumentError, TypeError
123
+ return number
124
+ end
125
+
126
+ options = {:delimiter => ',', :separator => '.'}
127
+ parts = number.to_s.to_str.split('.')
128
+ parts[0].gsub!(/(\d)(?=(\d\d\d)+(?!\d))/, "\\1#{options[:delimiter]}")
129
+ parts.join(options[:separator])
130
+ end
118
131
  end
119
132
 
120
133
  get "/" do
@@ -9,7 +9,7 @@ Gem::Specification.new do |gem|
9
9
  gem.license = "LGPL-3.0"
10
10
 
11
11
  gem.executables = ['sidekiq', 'sidekiqctl']
12
- gem.files = `git ls-files`.split("\n")
12
+ gem.files = `git ls-files | grep -v myapp`.split("\n")
13
13
  gem.test_files = `git ls-files -- test/*`.split("\n")
14
14
  gem.name = "sidekiq"
15
15
  gem.require_paths = ["lib"]
@@ -17,7 +17,7 @@ Gem::Specification.new do |gem|
17
17
  gem.add_dependency 'redis', '~> 3'
18
18
  gem.add_dependency 'redis-namespace'
19
19
  gem.add_dependency 'connection_pool', '~> 0.9.2'
20
- gem.add_dependency 'celluloid', '~> 0.11.1'
20
+ gem.add_dependency 'celluloid', '~> 0.12.0'
21
21
  gem.add_dependency 'multi_json', '~> 1'
22
22
  gem.add_development_dependency 'minitest', '~> 3'
23
23
  gem.add_development_dependency 'sinatra'
@@ -25,4 +25,5 @@ Gem::Specification.new do |gem|
25
25
  gem.add_development_dependency 'rake'
26
26
  gem.add_development_dependency 'actionmailer', '~> 3'
27
27
  gem.add_development_dependency 'activerecord', '~> 3'
28
+ gem.add_development_dependency 'pry'
28
29
  end
@@ -4,6 +4,8 @@ if ENV.has_key?("SIMPLECOV")
4
4
  SimpleCov.start
5
5
  end
6
6
 
7
+ require 'pry'
8
+
7
9
  require 'minitest/unit'
8
10
  require 'minitest/pride'
9
11
  require 'minitest/autorun'
@@ -69,6 +69,13 @@ class TestClient < MiniTest::Unit::TestCase
69
69
  @redis.verify
70
70
  end
71
71
 
72
+ it 'enqueues messages to redis' do
73
+ @redis.expect :rpush, 1, ['queue:custom_queue', String]
74
+ pushed = Sidekiq::Client.enqueue_to(:custom_queue, MyWorker, 1, 2)
75
+ assert pushed
76
+ @redis.verify
77
+ end
78
+
72
79
  class QueuedWorker
73
80
  include Sidekiq::Worker
74
81
  sidekiq_options :queue => :flimflam, :timeout => 1
@@ -49,7 +49,7 @@ class TestExceptionHandler < MiniTest::Unit::TestCase
49
49
  end
50
50
 
51
51
  it "notifies Airbrake" do
52
- ::Airbrake.expect(:notify,nil,[TEST_EXCEPTION,:parameters => { :a => 1 }])
52
+ ::Airbrake.expect(:notify_or_ignore,nil,[TEST_EXCEPTION,:parameters => { :a => 1 }])
53
53
  Component.new.invoke_exception(:a => 1)
54
54
  ::Airbrake.verify
55
55
  end
@@ -11,6 +11,7 @@ class TestStats < MiniTest::Unit::TestCase
11
11
 
12
12
  class DumbWorker
13
13
  include Sidekiq::Worker
14
+ sidekiq_options :queue => 'dumbq'
14
15
 
15
16
  def perform(arg)
16
17
  raise 'bang' if arg == nil
@@ -31,15 +32,15 @@ class TestStats < MiniTest::Unit::TestCase
31
32
  boss.expect(:processor_done!, nil, [processor])
32
33
  boss.expect(:processor_done!, nil, [processor])
33
34
 
34
- assert_equal 0, conn.get('stat:failed').to_i
35
- assert_equal 0, conn.get('stat:processed').to_i
35
+ assert_equal 0, Sidekiq.info[:failed]
36
+ assert_equal 0, Sidekiq.info[:processed]
36
37
 
37
38
  processor.process(msg, 'xyzzy')
38
39
  processor.process(msg, 'xyzzy')
39
40
  processor.process(msg, 'xyzzy')
40
41
 
41
- assert_equal 0, conn.get('stat:failed').to_i
42
- assert_equal 3, conn.get('stat:processed').to_i
42
+ assert_equal 0, Sidekiq.info[:failed]
43
+ assert_equal 3, Sidekiq.info[:processed]
43
44
  end
44
45
  end
45
46
 
@@ -49,8 +50,8 @@ class TestStats < MiniTest::Unit::TestCase
49
50
 
50
51
  @redis.with do |conn|
51
52
  assert_equal [], conn.smembers('workers')
52
- assert_equal 0, conn.get('stat:failed').to_i
53
- assert_equal 0, conn.get('stat:processed').to_i
53
+ assert_equal 0, Sidekiq.info[:failed]
54
+ assert_equal 0, Sidekiq.info[:processed]
54
55
 
55
56
  processor = Sidekiq::Processor.new(boss)
56
57
 
@@ -59,8 +60,46 @@ class TestStats < MiniTest::Unit::TestCase
59
60
  processor.process(msg, 'xyzzy')
60
61
  end
61
62
 
62
- assert_equal 1, conn.get('stat:failed').to_i
63
- assert_equal 1, conn.get('stat:processed').to_i
63
+ assert_equal 1, Sidekiq.info[:failed]
64
+ assert_equal 1, Sidekiq.info[:processed]
65
+ end
66
+ end
67
+
68
+ describe "info counts" do
69
+ before do
70
+ @redis.with do |conn|
71
+ conn.rpush 'queue:foo', '{}'
72
+ conn.sadd 'queues', 'foo'
73
+
74
+ conn.rpush 'queue:bar', '{}'
75
+ conn.rpush 'queue:bar', '{}'
76
+ conn.sadd 'queues', 'bar'
77
+
78
+ conn.rpush 'queue:baz', '{}'
79
+ conn.sadd 'queues', 'baz'
80
+ end
81
+ end
82
+
83
+ describe "queues_with_sizes" do
84
+ it "returns queue names and corresponding job counts" do
85
+ assert_equal [["foo", 1], ["baz", 1], ["bar", 2]], Sidekiq.info[:queues_with_sizes]
86
+ end
87
+ end
88
+
89
+ describe "backlog" do
90
+ it "returns count of all jobs yet to be processed" do
91
+ assert_equal 4, Sidekiq.info[:backlog]
92
+ end
93
+ end
94
+
95
+ describe "size" do
96
+ it "returns size of queues" do
97
+ assert_equal 0, Sidekiq.size("foox")
98
+ assert_equal 1, Sidekiq.size(:foo)
99
+ assert_equal 1, Sidekiq.size("foo")
100
+ assert_equal 3, Sidekiq.size("foo", "bar")
101
+ assert_equal 4, Sidekiq.size
102
+ end
64
103
  end
65
104
  end
66
105