Last active
February 6, 2019 19:48
-
-
Save tbuehlmann/428308f5f0201fbf4b7833e64177e433 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# lib/sidekiq/middleware/server/retry_jobs_without_exception.rb | |
module Sidekiq | |
RetryWithoutException = Class.new(StandardError) | |
module Middleware | |
module Server | |
class RetryJobsWithoutException < RetryJobs | |
def call(worker, msg, queue) | |
begin | |
yield | |
rescue RetryWithoutException => exception | |
attempt_retry(worker, msg, queue, exception) if msg['retry'] | |
end | |
end | |
private | |
# Original: https://github.com/mperham/sidekiq/blob/v4.1.3/lib/sidekiq/middleware/server/retry_jobs.rb#L88-L137 | |
# | |
# This method overrides the original method with the only change being that after adding | |
# the job as a retry, it will _not_ raise an exception. | |
def attempt_retry(worker, msg, queue, exception) | |
max_retry_attempts = retry_attempts_from(msg['retry'], @max_retries) | |
msg['queue'] = if msg['retry_queue'] | |
msg['retry_queue'] | |
else | |
queue | |
end | |
# App code can stuff all sorts of crazy binary data into the error message | |
# that won't convert to JSON. | |
m = exception.message.to_s[0, 10_000] | |
if m.respond_to?(:scrub!) | |
m.force_encoding('utf-8') | |
m.scrub! | |
end | |
msg['error_message'] = m | |
msg['error_class'] = exception.class.name | |
count = if msg['retry_count'] | |
msg['retried_at'] = Time.now.to_f | |
msg['retry_count'] += 1 | |
else | |
msg['failed_at'] = Time.now.to_f | |
msg['retry_count'] = 0 | |
end | |
if msg['backtrace'] == true | |
msg['error_backtrace'] = exception.backtrace | |
elsif !msg['backtrace'] | |
# do nothing | |
elsif msg['backtrace'].to_i != 0 | |
msg['error_backtrace'] = exception.backtrace[0...msg['backtrace'].to_i] | |
end | |
if count < max_retry_attempts | |
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) | |
Sidekiq.redis do |conn| | |
conn.zadd('retry', retry_at.to_s, payload) | |
end | |
else | |
# Goodbye dear message, you (re)tried your best I'm sure. | |
retries_exhausted(worker, msg, exception) | |
end | |
# raise exception | |
end | |
end | |
end | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# config/initializers/sidekiq.rb | |
if Sidekiq::VERSION >= '4.1' && Sidekiq::VERSION < '5' | |
Sidekiq.configure_server do |config| | |
config.server_middleware do |chain| | |
chain.insert_before Sidekiq::Middleware::Server::RetryJobs, Sidekiq::Middleware::Server::RetryJobsWithoutException | |
end | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# app/jobs/some_job.rb | |
class SomeJob | |
include Sidekiq::Worker | |
sidekiq_options queue: :some_queue, retry: 8, backtrace: false | |
def perform | |
# … | |
raise Sidekiq::RetryWithoutException | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment