Skip to content

Instantly share code, notes, and snippets.

@benkimball
Created July 12, 2018 19:55
Show Gist options
  • Save benkimball/50fac4309bece024bce937af80419755 to your computer and use it in GitHub Desktop.
Save benkimball/50fac4309bece024bce937af80419755 to your computer and use it in GitHub Desktop.
One approach to exponential backoff in Ruby
##
# Call +fn+ up to +retries+ times or until it does not raise a StandardError,
# returning its result. While exceptions are raised, wait an increasing interval
# between attempts. The interval will increase as k^N.
#
# Examples
# myfun = lambda { raise "failed" }
# backoff(myfun) # calls myfun at time = 0, 1, 4, 11, 26, 57s
# backoff(myfun, retries: 2, k: 1) # calls at time 0, 1, 3, 6, 10, 15s
def backoff(fn, retries: 5, delay: 0, k: 2)
sleep(delay)
fn.call
rescue => e
if retries > 0
backoff(fn, retries: retries - 1, delay: delay * k + 1, k: k)
else
raise e
end
end
mock_network_call = -> { puts Time.now.to_i; raise "hi" }
backoff(mock_network_call)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment