I am migrating a background job processing service made with sidekiq to shoryuken, which is based on Amazon SQS.
With sidekiq you can customize the retries pattern by using sidekiq_retry_in
:
class WorkerWithCustomRetry
include Sidekiq::Worker
sidekiq_options :retry => 5
sidekiq_retry_in do |count|
retry_count(count)
end
def self.retry_count(count)
...
end
end
where, in my case, retry_count
returns the delay for the next retry based on external configuration.
With shoryuken retries are yielded to SQS which handle retries automatically as long as the message is not deleted by the consumer application. However with shoryuken you can change the delay by using retry_intervals
but documentation only explains how to set fixed values:
class MyWorker
include Shoryuken::Worker
shoryuken_options queue: 'default', retry_intervals: [360, 1200, 3600] # 5.minutes, 20.minutes and 1.hour
end
I need to customize the delay for retries the same way as with sidekiq, using a retry_count
method which returns different values depending on external data. Is this possible or does exist a workaround to do that with shoryuken?
Currently Shoryuken only supports fixed values for exponential backoff, but you can submit a PR changing ExponentialBackoffRetry with:
# https://github.com/phstc/shoryuken/blob/290b1cb4c4c40f34881d7f7b7a3beda949099cf5/lib/shoryuken/middleware/server/exponential_backoff_retry.rb#L11
retry_intervals = worker.class.get_shoryuken_options['retry_intervals']
retry_intervals = if retry_intervals.respond_to? :call
retry_intervals.call(worker, queue, sqs_msg, body)
else
Array(retry_intervals)
end
So you will be able to use a proc or fixed values to set retry_intervals
, i.e.:
class MyWorker
include Shoryuken::Worker
shoryuken_options queue: 'default',
retry_intervals: -> (worker, queue, sqs_msg, body) { worker.your_method(...) }
end
OR you can remove the default ExponentialBackoffRetry
and add yours:
Shoryuken.configure_server do |config|
config.server_middleware do |chain|
chain.remove Middleware::Server::ExponentialBackoffRetry
chain.add YourExponentialBackoffRetry
end
end
But keep in mind that SQS does not officially support exponential backoff, it's something implemented in Shoryuken using the Visibility Timeout, which can extended to a maximum of 12 hours.
You can continue to call ChangeMessageVisibility to extend the visibility timeout to a maximum of 12 hours. If you try to extend beyond 12 hours, the request will be rejected.