retry.py 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546
  1. import time
  2. from functools import wraps
  3. # https://www.saltycrane.com/blog/2009/11/trying-out-retry-decorator-python/
  4. def retry(ExceptionToCheck, tries=2, delay=1, backoff=1, logger=None):
  5. """
  6. Retry calling the decorated function using an exponential backoff.
  7. http://www.saltycrane.com/blog/2009/11/trying-out-retry-decorator-python/
  8. original from: http://wiki.python.org/moin/PythonDecoratorLibrary#Retry
  9. :param ExceptionToCheck: the exception to check. may be a tuple of
  10. exceptions to check
  11. :type ExceptionToCheck: Exception or tuple
  12. :param tries: number of times to try (not retry) before giving up
  13. :type tries: int
  14. :param delay: initial delay between retries in seconds
  15. :type delay: int
  16. :param backoff: backoff multiplier e.g. value of 2 will double the delay
  17. each retry
  18. :type backoff: int
  19. :param logger: logger to use. If None, print
  20. :type logger: logging.Logger instance
  21. """
  22. def deco_retry(f):
  23. @wraps(f)
  24. def f_retry(*args, **kwargs):
  25. mtries, mdelay = tries, delay
  26. while mtries > 1:
  27. try:
  28. return f(*args, **kwargs)
  29. except ExceptionToCheck as e:
  30. msg = "%s, Retrying in %d seconds..." % (str(e), mdelay)
  31. if logger:
  32. logger.warning(msg)
  33. else:
  34. print(msg)
  35. time.sleep(mdelay)
  36. mtries -= 1
  37. mdelay *= backoff
  38. return f(*args, **kwargs)
  39. return f_retry # true decorator
  40. return deco_retry