Skip to content

Instantly share code, notes, and snippets.

@billyshambrook
Last active April 27, 2020 03:11
Show Gist options
  • Save billyshambrook/7448432 to your computer and use it in GitHub Desktop.
Save billyshambrook/7448432 to your computer and use it in GitHub Desktop.
Exception retry
# Retry decorator with exponential backoff
def retry(tries, delay=3, backoff=2):
"""
Retries a function or method if exception is raised.
delay sets the initial delay in seconds, and backoff sets the factor by which
the delay should lengthen after each failure. backoff must be greater than 1,
or else it isn't really a backoff. tries must be at least 0, and delay
greater than 0.
"""
if backoff <= 1:
raise ValueError("backoff must be greater than 1")
tries = math.floor(tries)
if tries < 0:
raise ValueError("tries must be 0 or greater")
if delay <= 0:
raise ValueError("delay must be greater than 0")
def deco_retry(f):
def f_retry(*args, **kwargs):
mtries, mdelay = tries, delay # make mutable
completed = False
while not completed:
try:
return f(*args, **kwargs)
except Exception:
if not mtries:
logger.error("No retries left")
raise
mtries -= 1 # consume an attempt
logger.debug("Attempt failed, retrying in {}secs. ({} retries left)".format(
int(mdelay), int(mtries)))
time.sleep(mdelay) # wait...
mdelay *= backoff # make future wait longer
return f_retry # true decorator -> decorated function
return deco_retry # @retry(arg[, ...]) -> true decorator
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment