Skip to content

Instantly share code, notes, and snippets.

@benauthor
Created February 28, 2018 19:54
Show Gist options
  • Save benauthor/6961bd0995562b3f4226ca10030d4de9 to your computer and use it in GitHub Desktop.
Save benauthor/6961bd0995562b3f4226ca10030d4de9 to your computer and use it in GitHub Desktop.
python retries decorator
from time import sleep
class retriable(object):
"""
A retrying decorator with backoff.
Use it like so:
@retriable(tries=60, initial_backoff=60, backoff_multiplier=1)
def do_something(foo):
return this_might_explode(foo)
If side-effectful, you should make sure your decorated function is
safe to retry ad nauseum!
"""
def __init__(self, tries=3, initial_backoff=0.5, backoff_multiplier=2):
"""
:param int tries: how many times to try the function, at most
:param Union[int, float] initial_backoff: starting sleep in seconds
between tries
:param Union[int, float] backoff_multiplier: backoff multiple applied
after each attempt
"""
if tries < 1:
raise ValueError("give us at least one try")
self._tries = tries
self._backoff = initial_backoff
self._multiplier = backoff_multiplier
def __call__(self, fn, *args, **kwargs):
def decorator(*args, **kwargs):
tried = 0
backoff = self._backoff
while tried < self._tries:
try:
return fn(*args, **kwargs)
except Exception as e:
last_e = e
tried += 1
log.exception("retriable handled exception")
sleep(backoff)
backoff *= self._multiplier
log.error("retries exhausted")
raise last_e
return decorator
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment