Skip to content

Instantly share code, notes, and snippets.

@aviksama
Created September 25, 2018 07:52
Show Gist options
  • Save aviksama/fc241bc8a9a631402b792e54597d2d77 to your computer and use it in GitHub Desktop.
Save aviksama/fc241bc8a9a631402b792e54597d2d77 to your computer and use it in GitHub Desktop.
from functools import wraps
import gevent
import six
class DoRetry(object):
def __init__(self, times=2, interval=5, exponential_interval=True):
if not (interval > 0 and isinstance(times, int) and times > 0):
raise AttributeError('interval and times must be a positive')
self.times = times
self.interval = interval
self.is_exponential = exponential_interval
def __call__(self, func, *args, **kwargs):
@wraps(func)
def wrap(*args, **kwargs):
try_after = 0
elapsed = 0
while True:
elapsed += 1
gevent.sleep(try_after)
try:
retval = func(*args, **kwargs)
break
except Exception as e:
if self.times > elapsed:
if self.is_exponential:
try_after = self.interval ** elapsed
else:
try_after = self.interval
else:
ret = 'failed after %s %s' % (elapsed, 'try' if elapsed <= 1 else 'tries')
ex = RuntimeError(ret)
six.raise_from(e, ex)
return retval
return wrap
@DoRetry(3, 3)
def function_fails_forever(**kwargs):
raise ValueError("throwing a ValueError intentionally")
@DoRetry(3, 3)
def function_that_succeeds(**kwargs):
print("We are good")
return kwargs
if __name__ == '__main__':
threads = [gevent.spawn(function_fails_forever), gevent.spawn(function_that_succeeds)]
gevent.joinall(threads)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment