Skip to content

Instantly share code, notes, and snippets.

@jumping
Forked from aviksama/simple_retry.py
Created October 14, 2019 02:50
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jumping/173e72dea861c3cc873559037336d29f to your computer and use it in GitHub Desktop.
Save jumping/173e72dea861c3cc873559037336d29f to your computer and use it in GitHub Desktop.
import os
import sys
from functools import wraps
import gevent
import six
sys.stderr = open(os.devnull, 'w')
class DoRetry(object):
def __init__(self, times=2, interval=5, exponential_interval=True, inject_attempts=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
self.inject_attempts = inject_attempts
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:
if self.inject_attempts:
kwargs.update({'attempts': elapsed})
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, inject_attempts=False)
def function_fails_forever(**kwargs):
func_name = 'function_fails_forever'
counter = kwargs.get('attempts', 0)
print('attempting %s' % func_name)
if counter < 3:
raise Exception("counter has not met particaular criteria")
return "%s ~ retries successful after %s times" % (func_name, counter)
@DoRetry(3, 3)
def function_succeeds_after_retries(**kwargs):
func_name = 'function_succeeds_after_retries'
counter = kwargs.get('attempts', 0)
print ('%s ~ attempt %s' % (func_name, counter))
if counter < 3:
raise Exception("counter has not met particaular criteria")
return "%s ~ retries successful after %s times" % (func_name, counter)
if __name__ == '__main__':
g1 = gevent.spawn(function_fails_forever)
g2 = gevent.spawn(function_succeeds_after_retries)
threads = [g1, g2]
gevent.joinall(threads)
print('function_fails_forever returned :: %s' % (g1.value))
print('function_succeeds_after_retries returned :: %s' % (g2.value))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment