Guest User

Untitled

a guest
May 22nd, 2018
72
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 1.78 KB | None | 0 0
  1. import functools
  2. import time
  3. import logging
  4.  
  5.  
  6. logging.basicConfig(level=logging.DEBUG, format='%(message)s')
  7. logger = logging.getLogger(__name__)
  8.  
  9.  
  10. def retry(predicate=None, max_tries=3, max_delay=60,
  11. delay_s=1, exponential=False):
  12. if predicate is None:
  13. predicate = bool
  14.  
  15. def decorator(f):
  16. def it():
  17. def factor(p):
  18. if exponential:
  19. return pow(2, p)
  20. return 1
  21.  
  22. for p in range(max_tries):
  23. yield min(factor(p) * delay_s, max_delay)
  24.  
  25. @functools.wraps(f)
  26. def wrapper(*args, **kwargs):
  27. last_e = None
  28. for delay in it():
  29. try:
  30. result = f(*args, **kwargs)
  31. except BaseException as e:
  32. last_e = e
  33. logger.exception('error in retry decorator!')
  34. else:
  35. if predicate(result):
  36. return result
  37. logger.debug('retrying after {} seconds'.format(delay))
  38. time.sleep(delay)
  39. if last_e:
  40. raise last_e
  41. raise Exception('No more retries!')
  42. return wrapper
  43. return decorator
  44.  
  45.  
  46. if __name__ == '__main__':
  47. def flaky(n_errors=0, max_tries=5,
  48. predicate=lambda _: True, exponential=True):
  49. n = {'errors': n_errors}
  50.  
  51. @retry(max_tries=max_tries,
  52. predicate=predicate, exponential=exponential)
  53. def f():
  54. if n['errors'] <= 0:
  55. return 'success!'
  56. n['errors'] -= 1
  57. raise Exception('boom!')
  58. return f
  59.  
  60. # within retry limit
  61. f = flaky(n_errors=3, max_tries=5)
  62. print(f())
  63.  
  64. # no more retries
  65. f = flaky(n_errors=3, max_tries=3)
  66. print(f())
Add Comment
Please, Sign In to add comment