From 172434d4598b86a866a2cffbf0a05811f5d93cf9 Mon Sep 17 00:00:00 2001 From: James Kassemi Date: Mon, 18 Mar 2013 15:20:28 -0600 Subject: [PATCH] Call 'exhausted' worker method after retries When the maximum number of retries is hit and the message is about to be thrown away, give the option of allowing the worker to say goodbye by defining an 'exhausted' method on the worker. --- lib/sidekiq/middleware/server/retry_jobs.rb | 5 ++++- test/test_retry.rb | 12 ++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/lib/sidekiq/middleware/server/retry_jobs.rb b/lib/sidekiq/middleware/server/retry_jobs.rb index 55352046..1bc82167 100644 --- a/lib/sidekiq/middleware/server/retry_jobs.rb +++ b/lib/sidekiq/middleware/server/retry_jobs.rb @@ -14,7 +14,8 @@ module Sidekiq # 3. after a few days, a developer deploys a fix. the message is # reprocessed successfully. # 4. if 3 never happens, sidekiq will eventually give up and throw the - # message away. + # message away. If the worker defines a method called 'exhausted', this + # will be called before throwing the message away. # # A message looks like: # @@ -82,8 +83,10 @@ module Sidekiq end else # Goodbye dear message, you (re)tried your best I'm sure. + worker.exhausted(*msg['args']) if worker.respond_to?(:exhausted) logger.debug { "Dropping message after hitting the retry maximum: #{msg}" } end + raise e end diff --git a/test/test_retry.rb b/test/test_retry.rb index 1331a285..4546544b 100644 --- a/test/test_retry.rb +++ b/test/test_retry.rb @@ -167,6 +167,18 @@ class TestRetry < MiniTest::Unit::TestCase # MiniTest can't assert that a method call did NOT happen!? assert_raises(MockExpectationError) { @redis.verify } end + + it 'calls exhausted method on worker after too many retries if available' do + msg = {"class"=>"Bob", "args"=>[1, 2, "foo"], "queue"=>"default", "error_message"=>"kerblammo!", "error_class"=>"RuntimeError", "failed_at"=>Time.now.utc, "retry"=>3, "retry_count"=>3} + worker = MiniTest::Mock.new + worker.expect :exhausted, true, [1, 2, "foo"] + handler = Sidekiq::Middleware::Server::RetryJobs.new + assert_raises RuntimeError do + handler.call(worker, msg, 'default') do + raise "kerblammo!" + end + end + end end describe 'poller' do