mirror of
https://github.com/mperham/sidekiq.git
synced 2022-11-09 13:52:34 -05:00
use 'retry' option to customize max retry attempts
e.g. { 'class' => 'HardWorker', 'args' => [1, 2, 'foo'], 'retry' => 5 } Addresses Issue #313
This commit is contained in:
parent
fc3a1fdc50
commit
bc1e38f85a
2 changed files with 51 additions and 3 deletions
|
@ -20,6 +20,13 @@ module Sidekiq
|
|||
#
|
||||
# { 'class' => 'HardWorker', 'args' => [1, 2, 'foo'] }
|
||||
#
|
||||
# The 'retry' option also accepts a number (in place of 'true'):
|
||||
#
|
||||
# { 'class' => 'HardWorker', 'args' => [1, 2, 'foo'], 'retry' => 5 }
|
||||
#
|
||||
# The job will be retried this number of times before giving up. (If simply
|
||||
# 'true', Sidekiq retries 25 times)
|
||||
#
|
||||
# We'll add a bit more data to the message to support retries:
|
||||
#
|
||||
# * 'queue' - the queue to use
|
||||
|
@ -35,13 +42,14 @@ module Sidekiq
|
|||
include Sidekiq::Util
|
||||
|
||||
# delayed_job uses the same basic formula
|
||||
MAX_COUNT = 25
|
||||
DEFAULT_MAX_RETRY_ATTEMPTS = 25
|
||||
DELAY = proc { |count| (count ** 4) + 15 }
|
||||
|
||||
def call(worker, msg, queue)
|
||||
yield
|
||||
rescue Exception => e
|
||||
raise e unless msg['retry']
|
||||
max_retry_attempts = retry_attempts_from(msg['retry'], DEFAULT_MAX_RETRY_ATTEMPTS)
|
||||
|
||||
msg['queue'] = queue
|
||||
msg['error_message'] = e.message
|
||||
|
@ -60,7 +68,7 @@ module Sidekiq
|
|||
msg['error_backtrace'] = e.backtrace[0..msg['backtrace'].to_i]
|
||||
end
|
||||
|
||||
if count <= MAX_COUNT
|
||||
if count <= max_retry_attempts
|
||||
delay = DELAY.call(count)
|
||||
logger.debug { "Failure! Retry #{count} in #{delay} seconds" }
|
||||
retry_at = Time.now.to_f + delay
|
||||
|
@ -75,6 +83,14 @@ module Sidekiq
|
|||
raise e
|
||||
end
|
||||
|
||||
def retry_attempts_from(msg_retry, default)
|
||||
if msg_retry.is_a?(Fixnum)
|
||||
msg_retry
|
||||
else
|
||||
default
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -88,7 +88,25 @@ class TestRetry < MiniTest::Unit::TestCase
|
|||
@redis.verify
|
||||
end
|
||||
|
||||
it 'throws away old messages after too many retries' do
|
||||
it 'handles a recurring failed message before reaching user-specifed max' do
|
||||
@redis.expect :zadd, 1, ['retry', String, String]
|
||||
now = Time.now.utc
|
||||
msg = {"class"=>"Bob", "args"=>[1, 2, "foo"], 'retry' => 11, "queue"=>"default", "error_message"=>"kerblammo!", "error_class"=>"RuntimeError", "failed_at"=>now, "retry_count"=>10}
|
||||
handler = Sidekiq::Middleware::Server::RetryJobs.new
|
||||
assert_raises RuntimeError do
|
||||
handler.call('', msg, 'default') do
|
||||
raise "kerblammo!"
|
||||
end
|
||||
end
|
||||
assert_equal 'default', msg["queue"]
|
||||
assert_equal 'kerblammo!', msg["error_message"]
|
||||
assert_equal 'RuntimeError', msg["error_class"]
|
||||
assert_equal 11, msg["retry_count"]
|
||||
assert msg["failed_at"]
|
||||
@redis.verify
|
||||
end
|
||||
|
||||
it 'throws away old messages after too many retries (using the default)' do
|
||||
now = Time.now.utc
|
||||
msg = {"class"=>"Bob", "args"=>[1, 2, "foo"], "queue"=>"default", "error_message"=>"kerblammo!", "error_class"=>"RuntimeError", "failed_at"=>now, "retry"=>true, "retry_count"=>25}
|
||||
@redis.expect :zadd, 1, [ 'retry', String, String ]
|
||||
|
@ -101,6 +119,20 @@ class TestRetry < MiniTest::Unit::TestCase
|
|||
# MiniTest can't assert that a method call did NOT happen!?
|
||||
assert_raises(MockExpectationError) { @redis.verify }
|
||||
end
|
||||
|
||||
it 'throws away old messages after too many retries (using user-specified max)' do
|
||||
now = Time.now.utc
|
||||
msg = {"class"=>"Bob", "args"=>[1, 2, "foo"], "queue"=>"default", "error_message"=>"kerblammo!", "error_class"=>"RuntimeError", "failed_at"=>now, "retry"=>3, "retry_count"=>3}
|
||||
@redis.expect :zadd, 1, [ 'retry', String, String ]
|
||||
handler = Sidekiq::Middleware::Server::RetryJobs.new
|
||||
assert_raises RuntimeError do
|
||||
handler.call('', msg, 'default') do
|
||||
raise "kerblammo!"
|
||||
end
|
||||
end
|
||||
# MiniTest can't assert that a method call did NOT happen!?
|
||||
assert_raises(MockExpectationError) { @redis.verify }
|
||||
end
|
||||
end
|
||||
|
||||
describe 'poller' do
|
||||
|
|
Loading…
Add table
Reference in a new issue