From b57b40d7f847ad72d91fdfccf9510368161c0f03 Mon Sep 17 00:00:00 2001 From: Brandon Hilkert Date: Tue, 4 Dec 2012 08:11:25 -0500 Subject: [PATCH 01/12] Add Stats API. --- lib/sidekiq/api.rb | 30 ++++++++++++++++++++++ lib/sidekiq/stats.rb | 10 -------- test/test_api.rb | 60 ++++++++++++++++++++++++++++++++++++++++++++ test/test_stats.rb | 9 ------- 4 files changed, 90 insertions(+), 19 deletions(-) diff --git a/lib/sidekiq/api.rb b/lib/sidekiq/api.rb index efe17501..a1d880c2 100644 --- a/lib/sidekiq/api.rb +++ b/lib/sidekiq/api.rb @@ -2,6 +2,36 @@ require 'sidekiq' module Sidekiq + class Stats + def processed + Sidekiq.redis do |conn| + conn.get("stat:processed") + end || 0 + end + + def failed + Sidekiq.redis do |conn| + conn.get("stat:failed") + end || 0 + end + + def queues + queues = Sidekiq.redis { |conn| conn.smembers('queues') } + + Sidekiq.redis do |conn| + queues.inject({}) do |memo, queue| + memo[queue] = conn.llen("queue:#{queue}") + memo + end + end + end + + def queued + queues.values.inject(&:+) || 0 + end + + end + ## # Encapsulates a queue within Sidekiq. # Allows enumeration of all jobs within the queue diff --git a/lib/sidekiq/stats.rb b/lib/sidekiq/stats.rb index 8108dc44..7f60e5a2 100644 --- a/lib/sidekiq/stats.rb +++ b/lib/sidekiq/stats.rb @@ -23,14 +23,4 @@ module Sidekiq inject(0) {|memo, val| memo + val } results end - - def size(*queues) - return info[:backlog] if queues.empty? - - Sidekiq.redis { |conn| - conn.multi { - queues.map { |q| conn.llen("queue:#{q}") } - } - }.inject(0) { |memo, count| memo += count } - end end diff --git a/test/test_api.rb b/test/test_api.rb index ef040b5f..e8f4709a 100644 --- a/test/test_api.rb +++ b/test/test_api.rb @@ -1,6 +1,66 @@ require 'helper' class TestApi < MiniTest::Unit::TestCase + describe "stats" do + before do + Sidekiq.redis {|c| c.flushdb } + end + + describe "processed" do + it "is initially zero" do + s = Sidekiq::Stats.new + assert_equal 0, s.processed + end + end + + describe "failed" do + it "is initially zero" do + s = Sidekiq::Stats.new + assert_equal 0, s.processed + end + end + + describe "queues" do + it "is initially empty" do + s = Sidekiq::Stats.new + assert_equal 0, s.queues.size + end + + it "returns a hash of queue and size" do + Sidekiq.redis do |conn| + conn.rpush 'queue:foo', '{}' + conn.sadd 'queues', 'foo' + + 3.times { conn.rpush 'queue:bar', '{}' } + conn.sadd 'queues', 'bar' + end + + s = Sidekiq::Stats.new + assert_equal ({ "foo" => 1, "bar" => 3 }), s.queues + end + end + + describe "queued" do + it "is initially empty" do + s = Sidekiq::Stats.new + assert_equal 0, s.queued + end + + it "returns total queued jobs" do + Sidekiq.redis do |conn| + conn.rpush 'queue:foo', '{}' + conn.sadd 'queues', 'foo' + + 3.times { conn.rpush 'queue:bar', '{}' } + conn.sadd 'queues', 'bar' + end + + s = Sidekiq::Stats.new + assert_equal 4, s.queued + end + end + end + describe 'with an empty database' do before do Sidekiq.redis {|c| c.flushdb } diff --git a/test/test_stats.rb b/test/test_stats.rb index 10202f3e..cd98bfae 100644 --- a/test/test_stats.rb +++ b/test/test_stats.rb @@ -92,15 +92,6 @@ class TestStats < MiniTest::Unit::TestCase end end - describe "size" do - it "returns size of queues" do - assert_equal 0, Sidekiq.size("foox") - assert_equal 1, Sidekiq.size(:foo) - assert_equal 1, Sidekiq.size("foo") - assert_equal 4, Sidekiq.size("foo", "bar") - assert_equal 6, Sidekiq.size - end - end end end From 8cae74444224305e70f7983926aeececbc000ab3 Mon Sep 17 00:00:00 2001 From: Brandon Hilkert Date: Tue, 4 Dec 2012 12:13:47 -0500 Subject: [PATCH 02/12] Add size back. --- lib/sidekiq/stats.rb | 10 ++++++++++ test/test_stats.rb | 9 +++++++++ 2 files changed, 19 insertions(+) diff --git a/lib/sidekiq/stats.rb b/lib/sidekiq/stats.rb index 7f60e5a2..8108dc44 100644 --- a/lib/sidekiq/stats.rb +++ b/lib/sidekiq/stats.rb @@ -23,4 +23,14 @@ module Sidekiq inject(0) {|memo, val| memo + val } results end + + def size(*queues) + return info[:backlog] if queues.empty? + + Sidekiq.redis { |conn| + conn.multi { + queues.map { |q| conn.llen("queue:#{q}") } + } + }.inject(0) { |memo, count| memo += count } + end end diff --git a/test/test_stats.rb b/test/test_stats.rb index cd98bfae..10202f3e 100644 --- a/test/test_stats.rb +++ b/test/test_stats.rb @@ -92,6 +92,15 @@ class TestStats < MiniTest::Unit::TestCase end end + describe "size" do + it "returns size of queues" do + assert_equal 0, Sidekiq.size("foox") + assert_equal 1, Sidekiq.size(:foo) + assert_equal 1, Sidekiq.size("foo") + assert_equal 4, Sidekiq.size("foo", "bar") + assert_equal 6, Sidekiq.size + end + end end end From 436bd0e9ecf99a71fa117d9a9665b20f78272daf Mon Sep 17 00:00:00 2001 From: Brandon Hilkert Date: Tue, 4 Dec 2012 12:18:05 -0500 Subject: [PATCH 03/12] * Change instance methods to class methods * Run queues in same redis connection * Change name of queued to enqueued --- lib/sidekiq/api.rb | 41 +++++++++++++++++++++-------------------- test/test_api.rb | 21 ++++++++------------- 2 files changed, 29 insertions(+), 33 deletions(-) diff --git a/lib/sidekiq/api.rb b/lib/sidekiq/api.rb index a1d880c2..2e9bd534 100644 --- a/lib/sidekiq/api.rb +++ b/lib/sidekiq/api.rb @@ -3,33 +3,34 @@ require 'sidekiq' module Sidekiq class Stats - def processed - Sidekiq.redis do |conn| - conn.get("stat:processed") - end || 0 - end + class << self + def processed + Sidekiq.redis do |conn| + conn.get("stat:processed") + end || 0 + end - def failed - Sidekiq.redis do |conn| - conn.get("stat:failed") - end || 0 - end + def failed + Sidekiq.redis do |conn| + conn.get("stat:failed") + end || 0 + end - def queues - queues = Sidekiq.redis { |conn| conn.smembers('queues') } + def queues + Sidekiq.redis do |conn| + queues = conn.smembers('queues') - Sidekiq.redis do |conn| - queues.inject({}) do |memo, queue| - memo[queue] = conn.llen("queue:#{queue}") - memo + queues.inject({}) do |memo, queue| + memo[queue] = conn.llen("queue:#{queue}") + memo + end end end - end - def queued - queues.values.inject(&:+) || 0 + def enqueued + queues.values.inject(&:+) || 0 + end end - end ## diff --git a/test/test_api.rb b/test/test_api.rb index e8f4709a..459a6088 100644 --- a/test/test_api.rb +++ b/test/test_api.rb @@ -8,22 +8,20 @@ class TestApi < MiniTest::Unit::TestCase describe "processed" do it "is initially zero" do - s = Sidekiq::Stats.new - assert_equal 0, s.processed + assert_equal 0, Sidekiq::Stats.processed end end describe "failed" do it "is initially zero" do - s = Sidekiq::Stats.new - assert_equal 0, s.processed + assert_equal 0, Sidekiq::Stats.processed end end describe "queues" do it "is initially empty" do s = Sidekiq::Stats.new - assert_equal 0, s.queues.size + assert_equal 0, Sidekiq::Stats.queues.size end it "returns a hash of queue and size" do @@ -35,18 +33,16 @@ class TestApi < MiniTest::Unit::TestCase conn.sadd 'queues', 'bar' end - s = Sidekiq::Stats.new - assert_equal ({ "foo" => 1, "bar" => 3 }), s.queues + assert_equal ({ "foo" => 1, "bar" => 3 }), Sidekiq::Stats.queues end end - describe "queued" do + describe "enqueued" do it "is initially empty" do - s = Sidekiq::Stats.new - assert_equal 0, s.queued + assert_equal 0, Sidekiq::Stats.enqueued end - it "returns total queued jobs" do + it "returns total enqueued jobs" do Sidekiq.redis do |conn| conn.rpush 'queue:foo', '{}' conn.sadd 'queues', 'foo' @@ -55,8 +51,7 @@ class TestApi < MiniTest::Unit::TestCase conn.sadd 'queues', 'bar' end - s = Sidekiq::Stats.new - assert_equal 4, s.queued + assert_equal 4, Sidekiq::Stats.enqueued end end end From d64e32629961681ab2bbd0bf14296847172123de Mon Sep 17 00:00:00 2001 From: Brandon Hilkert Date: Tue, 4 Dec 2012 13:14:38 -0500 Subject: [PATCH 04/12] * Revert instance methods * Add better test coverage --- lib/sidekiq/api.rb | 42 +++++++++++++++++++++--------------------- test/test_api.rb | 29 +++++++++++++++++++++++------ 2 files changed, 44 insertions(+), 27 deletions(-) diff --git a/lib/sidekiq/api.rb b/lib/sidekiq/api.rb index 2e9bd534..00dffcda 100644 --- a/lib/sidekiq/api.rb +++ b/lib/sidekiq/api.rb @@ -3,33 +3,33 @@ require 'sidekiq' module Sidekiq class Stats - class << self - def processed - Sidekiq.redis do |conn| - conn.get("stat:processed") - end || 0 - end + def processed + count = Sidekiq.redis do |conn| + conn.get("stat:processed") + end + count.nil? ? 0 : count.to_i + end - def failed - Sidekiq.redis do |conn| - conn.get("stat:failed") - end || 0 - end + def failed + count = Sidekiq.redis do |conn| + conn.get("stat:failed") + end + count.nil? ? 0 : count.to_i + end - def queues - Sidekiq.redis do |conn| - queues = conn.smembers('queues') + def queues + Sidekiq.redis do |conn| + queues = conn.smembers('queues') - queues.inject({}) do |memo, queue| - memo[queue] = conn.llen("queue:#{queue}") - memo - end + queues.inject({}) do |memo, queue| + memo[queue] = conn.llen("queue:#{queue}") + memo end end + end - def enqueued - queues.values.inject(&:+) || 0 - end + def enqueued + queues.values.inject(&:+) || 0 end end diff --git a/test/test_api.rb b/test/test_api.rb index 459a6088..a557d4a7 100644 --- a/test/test_api.rb +++ b/test/test_api.rb @@ -8,20 +8,34 @@ class TestApi < MiniTest::Unit::TestCase describe "processed" do it "is initially zero" do - assert_equal 0, Sidekiq::Stats.processed + s = Sidekiq::Stats.new + assert_equal 0, s.processed + end + + it "returns number of processed jobs" do + Sidekiq.redis { |conn| conn.set("stat:processed", 5) } + s = Sidekiq::Stats.new + assert_equal 5, s.processed end end describe "failed" do it "is initially zero" do - assert_equal 0, Sidekiq::Stats.processed + s = Sidekiq::Stats.new + assert_equal 0, s.processed + end + + it "returns number of failed jobs" do + Sidekiq.redis { |conn| conn.set("stat:failed", 5) } + s = Sidekiq::Stats.new + assert_equal 5, s.failed end end describe "queues" do it "is initially empty" do s = Sidekiq::Stats.new - assert_equal 0, Sidekiq::Stats.queues.size + assert_equal 0, s.queues.size end it "returns a hash of queue and size" do @@ -33,13 +47,15 @@ class TestApi < MiniTest::Unit::TestCase conn.sadd 'queues', 'bar' end - assert_equal ({ "foo" => 1, "bar" => 3 }), Sidekiq::Stats.queues + s = Sidekiq::Stats.new + assert_equal ({ "foo" => 1, "bar" => 3 }), s.queues end end describe "enqueued" do it "is initially empty" do - assert_equal 0, Sidekiq::Stats.enqueued + s = Sidekiq::Stats.new + assert_equal 0, s.enqueued end it "returns total enqueued jobs" do @@ -51,7 +67,8 @@ class TestApi < MiniTest::Unit::TestCase conn.sadd 'queues', 'bar' end - assert_equal 4, Sidekiq::Stats.enqueued + s = Sidekiq::Stats.new + assert_equal 4, s.enqueued end end end From 005c868d2c838410b966fed0adde21c79f625e99 Mon Sep 17 00:00:00 2001 From: Brandon Hilkert Date: Tue, 4 Dec 2012 08:11:25 -0500 Subject: [PATCH 05/12] Add Stats API. --- lib/sidekiq/api.rb | 30 ++++++++++++++++++++++ lib/sidekiq/stats.rb | 10 -------- test/test_api.rb | 60 ++++++++++++++++++++++++++++++++++++++++++++ test/test_stats.rb | 9 ------- 4 files changed, 90 insertions(+), 19 deletions(-) diff --git a/lib/sidekiq/api.rb b/lib/sidekiq/api.rb index efe17501..a1d880c2 100644 --- a/lib/sidekiq/api.rb +++ b/lib/sidekiq/api.rb @@ -2,6 +2,36 @@ require 'sidekiq' module Sidekiq + class Stats + def processed + Sidekiq.redis do |conn| + conn.get("stat:processed") + end || 0 + end + + def failed + Sidekiq.redis do |conn| + conn.get("stat:failed") + end || 0 + end + + def queues + queues = Sidekiq.redis { |conn| conn.smembers('queues') } + + Sidekiq.redis do |conn| + queues.inject({}) do |memo, queue| + memo[queue] = conn.llen("queue:#{queue}") + memo + end + end + end + + def queued + queues.values.inject(&:+) || 0 + end + + end + ## # Encapsulates a queue within Sidekiq. # Allows enumeration of all jobs within the queue diff --git a/lib/sidekiq/stats.rb b/lib/sidekiq/stats.rb index 8108dc44..7f60e5a2 100644 --- a/lib/sidekiq/stats.rb +++ b/lib/sidekiq/stats.rb @@ -23,14 +23,4 @@ module Sidekiq inject(0) {|memo, val| memo + val } results end - - def size(*queues) - return info[:backlog] if queues.empty? - - Sidekiq.redis { |conn| - conn.multi { - queues.map { |q| conn.llen("queue:#{q}") } - } - }.inject(0) { |memo, count| memo += count } - end end diff --git a/test/test_api.rb b/test/test_api.rb index ef040b5f..e8f4709a 100644 --- a/test/test_api.rb +++ b/test/test_api.rb @@ -1,6 +1,66 @@ require 'helper' class TestApi < MiniTest::Unit::TestCase + describe "stats" do + before do + Sidekiq.redis {|c| c.flushdb } + end + + describe "processed" do + it "is initially zero" do + s = Sidekiq::Stats.new + assert_equal 0, s.processed + end + end + + describe "failed" do + it "is initially zero" do + s = Sidekiq::Stats.new + assert_equal 0, s.processed + end + end + + describe "queues" do + it "is initially empty" do + s = Sidekiq::Stats.new + assert_equal 0, s.queues.size + end + + it "returns a hash of queue and size" do + Sidekiq.redis do |conn| + conn.rpush 'queue:foo', '{}' + conn.sadd 'queues', 'foo' + + 3.times { conn.rpush 'queue:bar', '{}' } + conn.sadd 'queues', 'bar' + end + + s = Sidekiq::Stats.new + assert_equal ({ "foo" => 1, "bar" => 3 }), s.queues + end + end + + describe "queued" do + it "is initially empty" do + s = Sidekiq::Stats.new + assert_equal 0, s.queued + end + + it "returns total queued jobs" do + Sidekiq.redis do |conn| + conn.rpush 'queue:foo', '{}' + conn.sadd 'queues', 'foo' + + 3.times { conn.rpush 'queue:bar', '{}' } + conn.sadd 'queues', 'bar' + end + + s = Sidekiq::Stats.new + assert_equal 4, s.queued + end + end + end + describe 'with an empty database' do before do Sidekiq.redis {|c| c.flushdb } diff --git a/test/test_stats.rb b/test/test_stats.rb index 10202f3e..cd98bfae 100644 --- a/test/test_stats.rb +++ b/test/test_stats.rb @@ -92,15 +92,6 @@ class TestStats < MiniTest::Unit::TestCase end end - describe "size" do - it "returns size of queues" do - assert_equal 0, Sidekiq.size("foox") - assert_equal 1, Sidekiq.size(:foo) - assert_equal 1, Sidekiq.size("foo") - assert_equal 4, Sidekiq.size("foo", "bar") - assert_equal 6, Sidekiq.size - end - end end end From 7719effdee83ec439c431fec9fb559d1d3128cbf Mon Sep 17 00:00:00 2001 From: Brandon Hilkert Date: Tue, 4 Dec 2012 12:13:47 -0500 Subject: [PATCH 06/12] Add size back. --- lib/sidekiq/stats.rb | 10 ++++++++++ test/test_stats.rb | 9 +++++++++ 2 files changed, 19 insertions(+) diff --git a/lib/sidekiq/stats.rb b/lib/sidekiq/stats.rb index 7f60e5a2..8108dc44 100644 --- a/lib/sidekiq/stats.rb +++ b/lib/sidekiq/stats.rb @@ -23,4 +23,14 @@ module Sidekiq inject(0) {|memo, val| memo + val } results end + + def size(*queues) + return info[:backlog] if queues.empty? + + Sidekiq.redis { |conn| + conn.multi { + queues.map { |q| conn.llen("queue:#{q}") } + } + }.inject(0) { |memo, count| memo += count } + end end diff --git a/test/test_stats.rb b/test/test_stats.rb index cd98bfae..10202f3e 100644 --- a/test/test_stats.rb +++ b/test/test_stats.rb @@ -92,6 +92,15 @@ class TestStats < MiniTest::Unit::TestCase end end + describe "size" do + it "returns size of queues" do + assert_equal 0, Sidekiq.size("foox") + assert_equal 1, Sidekiq.size(:foo) + assert_equal 1, Sidekiq.size("foo") + assert_equal 4, Sidekiq.size("foo", "bar") + assert_equal 6, Sidekiq.size + end + end end end From 4dcbec2ba2f2f42db3ce0cf5fe2e06e4ca78b568 Mon Sep 17 00:00:00 2001 From: Brandon Hilkert Date: Tue, 4 Dec 2012 12:18:05 -0500 Subject: [PATCH 07/12] * Change instance methods to class methods * Run queues in same redis connection * Change name of queued to enqueued --- lib/sidekiq/api.rb | 41 +++++++++++++++++++++-------------------- test/test_api.rb | 21 ++++++++------------- 2 files changed, 29 insertions(+), 33 deletions(-) diff --git a/lib/sidekiq/api.rb b/lib/sidekiq/api.rb index a1d880c2..2e9bd534 100644 --- a/lib/sidekiq/api.rb +++ b/lib/sidekiq/api.rb @@ -3,33 +3,34 @@ require 'sidekiq' module Sidekiq class Stats - def processed - Sidekiq.redis do |conn| - conn.get("stat:processed") - end || 0 - end + class << self + def processed + Sidekiq.redis do |conn| + conn.get("stat:processed") + end || 0 + end - def failed - Sidekiq.redis do |conn| - conn.get("stat:failed") - end || 0 - end + def failed + Sidekiq.redis do |conn| + conn.get("stat:failed") + end || 0 + end - def queues - queues = Sidekiq.redis { |conn| conn.smembers('queues') } + def queues + Sidekiq.redis do |conn| + queues = conn.smembers('queues') - Sidekiq.redis do |conn| - queues.inject({}) do |memo, queue| - memo[queue] = conn.llen("queue:#{queue}") - memo + queues.inject({}) do |memo, queue| + memo[queue] = conn.llen("queue:#{queue}") + memo + end end end - end - def queued - queues.values.inject(&:+) || 0 + def enqueued + queues.values.inject(&:+) || 0 + end end - end ## diff --git a/test/test_api.rb b/test/test_api.rb index e8f4709a..459a6088 100644 --- a/test/test_api.rb +++ b/test/test_api.rb @@ -8,22 +8,20 @@ class TestApi < MiniTest::Unit::TestCase describe "processed" do it "is initially zero" do - s = Sidekiq::Stats.new - assert_equal 0, s.processed + assert_equal 0, Sidekiq::Stats.processed end end describe "failed" do it "is initially zero" do - s = Sidekiq::Stats.new - assert_equal 0, s.processed + assert_equal 0, Sidekiq::Stats.processed end end describe "queues" do it "is initially empty" do s = Sidekiq::Stats.new - assert_equal 0, s.queues.size + assert_equal 0, Sidekiq::Stats.queues.size end it "returns a hash of queue and size" do @@ -35,18 +33,16 @@ class TestApi < MiniTest::Unit::TestCase conn.sadd 'queues', 'bar' end - s = Sidekiq::Stats.new - assert_equal ({ "foo" => 1, "bar" => 3 }), s.queues + assert_equal ({ "foo" => 1, "bar" => 3 }), Sidekiq::Stats.queues end end - describe "queued" do + describe "enqueued" do it "is initially empty" do - s = Sidekiq::Stats.new - assert_equal 0, s.queued + assert_equal 0, Sidekiq::Stats.enqueued end - it "returns total queued jobs" do + it "returns total enqueued jobs" do Sidekiq.redis do |conn| conn.rpush 'queue:foo', '{}' conn.sadd 'queues', 'foo' @@ -55,8 +51,7 @@ class TestApi < MiniTest::Unit::TestCase conn.sadd 'queues', 'bar' end - s = Sidekiq::Stats.new - assert_equal 4, s.queued + assert_equal 4, Sidekiq::Stats.enqueued end end end From 187e6e90bdfd708d67e673af1fabd1b1a34aed58 Mon Sep 17 00:00:00 2001 From: Brandon Hilkert Date: Tue, 4 Dec 2012 13:14:38 -0500 Subject: [PATCH 08/12] * Revert instance methods * Add better test coverage --- lib/sidekiq/api.rb | 42 +++++++++++++++++++++--------------------- test/test_api.rb | 29 +++++++++++++++++++++++------ 2 files changed, 44 insertions(+), 27 deletions(-) diff --git a/lib/sidekiq/api.rb b/lib/sidekiq/api.rb index 2e9bd534..00dffcda 100644 --- a/lib/sidekiq/api.rb +++ b/lib/sidekiq/api.rb @@ -3,33 +3,33 @@ require 'sidekiq' module Sidekiq class Stats - class << self - def processed - Sidekiq.redis do |conn| - conn.get("stat:processed") - end || 0 - end + def processed + count = Sidekiq.redis do |conn| + conn.get("stat:processed") + end + count.nil? ? 0 : count.to_i + end - def failed - Sidekiq.redis do |conn| - conn.get("stat:failed") - end || 0 - end + def failed + count = Sidekiq.redis do |conn| + conn.get("stat:failed") + end + count.nil? ? 0 : count.to_i + end - def queues - Sidekiq.redis do |conn| - queues = conn.smembers('queues') + def queues + Sidekiq.redis do |conn| + queues = conn.smembers('queues') - queues.inject({}) do |memo, queue| - memo[queue] = conn.llen("queue:#{queue}") - memo - end + queues.inject({}) do |memo, queue| + memo[queue] = conn.llen("queue:#{queue}") + memo end end + end - def enqueued - queues.values.inject(&:+) || 0 - end + def enqueued + queues.values.inject(&:+) || 0 end end diff --git a/test/test_api.rb b/test/test_api.rb index 459a6088..a557d4a7 100644 --- a/test/test_api.rb +++ b/test/test_api.rb @@ -8,20 +8,34 @@ class TestApi < MiniTest::Unit::TestCase describe "processed" do it "is initially zero" do - assert_equal 0, Sidekiq::Stats.processed + s = Sidekiq::Stats.new + assert_equal 0, s.processed + end + + it "returns number of processed jobs" do + Sidekiq.redis { |conn| conn.set("stat:processed", 5) } + s = Sidekiq::Stats.new + assert_equal 5, s.processed end end describe "failed" do it "is initially zero" do - assert_equal 0, Sidekiq::Stats.processed + s = Sidekiq::Stats.new + assert_equal 0, s.processed + end + + it "returns number of failed jobs" do + Sidekiq.redis { |conn| conn.set("stat:failed", 5) } + s = Sidekiq::Stats.new + assert_equal 5, s.failed end end describe "queues" do it "is initially empty" do s = Sidekiq::Stats.new - assert_equal 0, Sidekiq::Stats.queues.size + assert_equal 0, s.queues.size end it "returns a hash of queue and size" do @@ -33,13 +47,15 @@ class TestApi < MiniTest::Unit::TestCase conn.sadd 'queues', 'bar' end - assert_equal ({ "foo" => 1, "bar" => 3 }), Sidekiq::Stats.queues + s = Sidekiq::Stats.new + assert_equal ({ "foo" => 1, "bar" => 3 }), s.queues end end describe "enqueued" do it "is initially empty" do - assert_equal 0, Sidekiq::Stats.enqueued + s = Sidekiq::Stats.new + assert_equal 0, s.enqueued end it "returns total enqueued jobs" do @@ -51,7 +67,8 @@ class TestApi < MiniTest::Unit::TestCase conn.sadd 'queues', 'bar' end - assert_equal 4, Sidekiq::Stats.enqueued + s = Sidekiq::Stats.new + assert_equal 4, s.enqueued end end end From 3e22bfd58e5b3ba978b5b183138783c631872f37 Mon Sep 17 00:00:00 2001 From: Brandon Hilkert Date: Tue, 4 Dec 2012 16:57:48 -0500 Subject: [PATCH 09/12] Use new stats API in web UI. --- lib/sidekiq/web.rb | 18 +++++------------- web/views/_summary.slim | 4 ++-- web/views/queues.slim | 2 +- 3 files changed, 8 insertions(+), 16 deletions(-) diff --git a/lib/sidekiq/web.rb b/lib/sidekiq/web.rb index 55de9046..f80d8b1c 100644 --- a/lib/sidekiq/web.rb +++ b/lib/sidekiq/web.rb @@ -34,28 +34,20 @@ module Sidekiq end end - def info - @info ||= Sidekiq.info - end - def processed - info[:processed] + Sidekiq::Stats.new.processed end def failed - info[:failed] + Sidekiq::Stats.new.failed end def zcard(name) Sidekiq.redis { |conn| conn.zcard(name) } end - def queues - @queues ||= Sidekiq.info[:queues_with_sizes] - end - - def backlog - info[:backlog] + def enqueued + Sidekiq::Stats.new.enqueued end def retries_with_score(score) @@ -122,7 +114,7 @@ module Sidekiq end get "/queues" do - @queues = queues + @queues = Sidekiq::Stats.new.queues slim :queues end diff --git a/web/views/_summary.slim b/web/views/_summary.slim index 7b7c2397..c0201c27 100755 --- a/web/views/_summary.slim +++ b/web/views/_summary.slim @@ -15,5 +15,5 @@ ul.unstyled.summary span.count #{number_with_delimiter(zcard('retry'))} span.desc Retries li - span.count #{number_with_delimiter(backlog)} - span.desc Queue + span.count #{number_with_delimiter(enqueued)} + span.desc Enqueued diff --git a/web/views/queues.slim b/web/views/queues.slim index 5cb4aaac..f9f4f8ef 100755 --- a/web/views/queues.slim +++ b/web/views/queues.slim @@ -5,7 +5,7 @@ table class="queues table table-hover table-bordered table-striped table-white" th Queue th Size th Actions - - queues.each do |(queue, size)| + - @queues.each do |queue, size| tr td a href="#{root_path}queues/#{queue}" #{queue} From de55c8d5421b90d7c7fcf4b8f7017c42893a3ef1 Mon Sep 17 00:00:00 2001 From: Brandon Hilkert Date: Tue, 4 Dec 2012 17:05:47 -0500 Subject: [PATCH 10/12] Order queues by number enqueued. --- lib/sidekiq/api.rb | 6 ++++-- test/test_api.rb | 3 ++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/lib/sidekiq/api.rb b/lib/sidekiq/api.rb index 00dffcda..1e0ec355 100644 --- a/lib/sidekiq/api.rb +++ b/lib/sidekiq/api.rb @@ -21,10 +21,12 @@ module Sidekiq Sidekiq.redis do |conn| queues = conn.smembers('queues') - queues.inject({}) do |memo, queue| + array_of_arrays = queues.inject({}) do |memo, queue| memo[queue] = conn.llen("queue:#{queue}") memo - end + end.sort_by { |_, size| size } + + Hash[array_of_arrays.reverse] end end diff --git a/test/test_api.rb b/test/test_api.rb index a557d4a7..4e184666 100644 --- a/test/test_api.rb +++ b/test/test_api.rb @@ -38,7 +38,7 @@ class TestApi < MiniTest::Unit::TestCase assert_equal 0, s.queues.size end - it "returns a hash of queue and size" do + it "returns a hash of queue and size in order" do Sidekiq.redis do |conn| conn.rpush 'queue:foo', '{}' conn.sadd 'queues', 'foo' @@ -49,6 +49,7 @@ class TestApi < MiniTest::Unit::TestCase s = Sidekiq::Stats.new assert_equal ({ "foo" => 1, "bar" => 3 }), s.queues + assert_equal "bar", s.queues.first.first end end From 9ce4fec04364076d5ef1eed8592b0df04f7f220b Mon Sep 17 00:00:00 2001 From: Brandon Hilkert Date: Tue, 4 Dec 2012 17:10:42 -0500 Subject: [PATCH 11/12] Remove info for new stats API. --- lib/sidekiq/stats.rb | 25 +----------------- test/test_stats.rb | 60 -------------------------------------------- 2 files changed, 1 insertion(+), 84 deletions(-) diff --git a/lib/sidekiq/stats.rb b/lib/sidekiq/stats.rb index 8108dc44..dcf6c8b0 100644 --- a/lib/sidekiq/stats.rb +++ b/lib/sidekiq/stats.rb @@ -1,31 +1,8 @@ module Sidekiq module_function - def info - results = {} - processed, failed, queues = Sidekiq.redis { |conn| - conn.multi do - conn.get('stat:processed') - conn.get('stat:failed') - conn.smembers('queues') - end - } - results[:queues_with_sizes] = Sidekiq.redis do |conn| - queues.inject({}) { |memo, q| - memo[q] = conn.llen("queue:#{q}") - memo - }.sort_by { |_, size| size } - end - results[:processed] = (processed || 0).to_i - results[:failed] = (failed || 0).to_i - results[:backlog] = results[:queues_with_sizes]. - map {|_, size| size }. - inject(0) {|memo, val| memo + val } - results - end - def size(*queues) - return info[:backlog] if queues.empty? + return Sidekiq::Stats.new.enqueued if queues.empty? Sidekiq.redis { |conn| conn.multi { diff --git a/test/test_stats.rb b/test/test_stats.rb index 10202f3e..574a6614 100644 --- a/test/test_stats.rb +++ b/test/test_stats.rb @@ -18,54 +18,6 @@ class TestStats < MiniTest::Unit::TestCase end end - it 'updates global stats in the success case' do - msg = Sidekiq.dump_json({ 'class' => DumbWorker.to_s, 'args' => [""] }) - boss = MiniTest::Mock.new - actor = MiniTest::Mock.new - - @redis.with do |conn| - - set = conn.smembers('workers') - assert_equal 0, set.size - - processor = Sidekiq::Processor.new(boss) - 3.times do - actor.expect(:processor_done, nil, [processor]) - boss.expect(:async, actor, []) - end - - assert_equal 0, Sidekiq.info[:failed] - assert_equal 0, Sidekiq.info[:processed] - - processor.process(msg, 'xyzzy') - processor.process(msg, 'xyzzy') - processor.process(msg, 'xyzzy') - - assert_equal 0, Sidekiq.info[:failed] - assert_equal 3, Sidekiq.info[:processed] - end - end - - it 'updates global stats in the error case' do - msg = Sidekiq.dump_json({ 'class' => DumbWorker.to_s, 'args' => [nil] }) - boss = MiniTest::Mock.new - - @redis.with do |conn| - assert_equal [], conn.smembers('workers') - assert_equal 0, Sidekiq.info[:failed] - assert_equal 0, Sidekiq.info[:processed] - - processor = Sidekiq::Processor.new(boss) - - assert_raises RuntimeError do - processor.process(msg, 'xyzzy') - end - - assert_equal 1, Sidekiq.info[:failed] - assert_equal 1, Sidekiq.info[:processed] - end - end - describe "info counts" do before do @redis.with do |conn| @@ -80,18 +32,6 @@ class TestStats < MiniTest::Unit::TestCase end end - describe "queues_with_sizes" do - it "returns queue names and corresponding job counts" do - assert_equal [["foo", 1], ["baz", 2], ["bar", 3]], Sidekiq.info[:queues_with_sizes] - end - end - - describe "backlog" do - it "returns count of all jobs yet to be processed" do - assert_equal 6, Sidekiq.info[:backlog] - end - end - describe "size" do it "returns size of queues" do assert_equal 0, Sidekiq.size("foox") From 355cc3f604be034b033a2bf41c910936a75fba17 Mon Sep 17 00:00:00 2001 From: Brandon Hilkert Date: Wed, 5 Dec 2012 11:46:55 -0500 Subject: [PATCH 12/12] * Memoize stats instance * Create more indicative helpers for stats * Update example for Stats API --- examples/sinkiq.rb | 5 +++-- lib/sidekiq/web.rb | 16 ++++++---------- web/views/_summary.slim | 10 +++++----- 3 files changed, 14 insertions(+), 17 deletions(-) diff --git a/examples/sinkiq.rb b/examples/sinkiq.rb index 456b28c2..4f832571 100644 --- a/examples/sinkiq.rb +++ b/examples/sinkiq.rb @@ -19,8 +19,9 @@ class SinatraWorker end get '/' do - @failed = Sidekiq.info[:failed] - @processed = Sidekiq.info[:processed] + stats = Sidekiq::Stats.new + @failed = stats.failed + @processed = stats.processed @messages = $redis.lrange('sinkiq-example-messages', 0, -1) erb :index end diff --git a/lib/sidekiq/web.rb b/lib/sidekiq/web.rb index f80d8b1c..47b89be2 100644 --- a/lib/sidekiq/web.rb +++ b/lib/sidekiq/web.rb @@ -34,20 +34,16 @@ module Sidekiq end end - def processed - Sidekiq::Stats.new.processed + def stats + @stats ||= Sidekiq::Stats.new end - def failed - Sidekiq::Stats.new.failed + def scheduled_job_count + Sidekiq::ScheduledSet.new.size end - def zcard(name) - Sidekiq.redis { |conn| conn.zcard(name) } - end - - def enqueued - Sidekiq::Stats.new.enqueued + def retry_job_count + Sidekiq::RetrySet.new.size end def retries_with_score(score) diff --git a/web/views/_summary.slim b/web/views/_summary.slim index c0201c27..720720ae 100755 --- a/web/views/_summary.slim +++ b/web/views/_summary.slim @@ -1,19 +1,19 @@ ul.unstyled.summary li - span.count #{number_with_delimiter(processed)} + span.count #{number_with_delimiter(stats.processed)} span.desc Processed li - span.count #{number_with_delimiter(failed)} + span.count #{number_with_delimiter(stats.failed)} span.desc Failed li span.count #{number_with_delimiter(workers.size)} span.desc Busy li - span.count #{number_with_delimiter(zcard('schedule'))} + span.count #{number_with_delimiter(scheduled_job_count)} span.desc Scheduled li - span.count #{number_with_delimiter(zcard('retry'))} + span.count #{number_with_delimiter(retry_job_count)} span.desc Retries li - span.count #{number_with_delimiter(enqueued)} + span.count #{number_with_delimiter(stats.enqueued)} span.desc Enqueued