Skip to content

Instantly share code, notes, and snippets.

@bogdan

bogdan/retryable.rb

Created Jan 12, 2021
Embed
What would you like to do?
# Retry a block, from
#
# http://blog.codefront.net/2008/01/14/retrying-code-blocks-in-ruby-on-exceptions-whatever/
#
# Options:
# * :tries - Number of retries to perform. Defaults to 1.
# * :on - The Exception on which a retry will be performed. Defaults to Exception, which retries on any Exception.
# * :interval - Number of seconds to sleep between attempts
#
# Example
# =======
# retryable(tries: 1, on: OpenURI::HTTPError) do
# # your code here
# end
#
def retryable(tries: 1, on: StandardError, interval: 0)
retry_classes = Array(on)
(1..tries).each do |attempt|
begin
return yield
rescue => exception
Rails.logger.info '[RETRYABLE] ' + '_' * 120 + " attempt #{attempt} is failed"
if retry_classes.any?{|klass| exception.is_a?(klass) || exception.cause.is_a?(klass) }
if attempt >= tries
add_newrelic_custom_attributes(retried: :failed)
Rails.logger.info '[RETRYABLE] ' + '_' * 120 + " raise exception"
raise
end
add_newrelic_custom_attributes(retried: :run) if attempt == 1
sleep(interval) and interval *= 2 if interval > 0
Rails.logger.info '[RETRYABLE] ' + '_' * 120 + " start the next attempt"
else
raise
end
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment