Skip to content

Commit

Permalink
Make exception available in #sidekiq_retry_in
Browse files Browse the repository at this point in the history
  • Loading branch information
Kelley Reynolds committed Oct 23, 2015
1 parent deca1dc commit 2571086
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 10 deletions.
10 changes: 5 additions & 5 deletions lib/sidekiq/middleware/server/retry_jobs.rb
Expand Up @@ -121,7 +121,7 @@ def attempt_retry(worker, msg, queue, exception)
end

if count < max_retry_attempts
delay = delay_for(worker, count)
delay = delay_for(worker, count, exception)
logger.debug { "Failure! Retry #{count} in #{delay} seconds" }
retry_at = Time.now.to_f + delay
payload = Sidekiq.dump_json(msg)
Expand Down Expand Up @@ -170,18 +170,18 @@ def retry_attempts_from(msg_retry, default)
end
end

def delay_for(worker, count)
worker.sidekiq_retry_in_block? && retry_in(worker, count) || seconds_to_delay(count)
def delay_for(worker, count, exception)
worker.sidekiq_retry_in_block? && retry_in(worker, count, exception) || seconds_to_delay(count)
end

# delayed_job uses the same basic formula
def seconds_to_delay(count)
(count ** 4) + 15 + (rand(30)*(count+1))
end

def retry_in(worker, count)
def retry_in(worker, count, exception)
begin
worker.sidekiq_retry_in_block.call(count).to_i
worker.sidekiq_retry_in_block.call(count, exception).to_i
rescue Exception => e
handle_exception(e, { context: "Failure scheduling retry using the defined `sidekiq_retry_in` in #{worker.class.name}, falling back to default" })
nil
Expand Down
31 changes: 26 additions & 5 deletions test/test_retry.rb
Expand Up @@ -229,14 +229,27 @@ def job(options={})
File.unlink @tmp_log_path if File.exist?(@tmp_log_path)
end

class CustomWorker
class CustomWorkerWithoutException
include Sidekiq::Worker

sidekiq_retry_in do |count|
count * 2
end
end

class CustomWorkerWithException
include Sidekiq::Worker

sidekiq_retry_in do |count, exception|
case exception
when ArgumentError
count * 4
else
count * 2
end
end
end

class ErrorWorker
include Sidekiq::Worker

Expand All @@ -246,15 +259,23 @@ class ErrorWorker
end

it "retries with a default delay" do
refute_equal 4, handler.__send__(:delay_for, worker, 2)
refute_equal 4, handler.__send__(:delay_for, worker, 2, StandardError.new)
end

it "retries with a custom delay and exception 1" do
assert_equal 8, handler.__send__(:delay_for, CustomWorkerWithException, 2, ArgumentError.new)
end

it "retries with a custom delay and exception 2" do
assert_equal 4, handler.__send__(:delay_for, CustomWorkerWithException, 2, StandardError.new)
end

it "retries with a custom delay" do
assert_equal 4, handler.__send__(:delay_for, CustomWorker, 2)
it "retries with a custom delay without exception" do
assert_equal 4, handler.__send__(:delay_for, CustomWorkerWithoutException, 2, StandardError.new)
end

it "falls back to the default retry on exception" do
refute_equal 4, handler.__send__(:delay_for, ErrorWorker, 2)
refute_equal 4, handler.__send__(:delay_for, ErrorWorker, 2, StandardError.new)
assert_match(/Failure scheduling retry using the defined `sidekiq_retry_in`/,
File.read(@tmp_log_path), 'Log entry missing for sidekiq_retry_in')
end
Expand Down

0 comments on commit 2571086

Please sign in to comment.