Created
February 12, 2020 00:01
-
-
Save MihanixA/83c6309bfd1e01ccea456c921a60bb0d to your computer and use it in GitHub Desktop.
Python Exponential Retry Decorator
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import time | |
import math | |
from copy import deepcopy | |
from typing import List, Type, Union, Callable, Any, Optional | |
from functools import wraps | |
def exp_retry(count: int = 5, power: Union[int, float] = 2, ignore_exceptions: List[Type[BaseException]] = None, | |
raise_on_failure: Optional[Type[BaseException]] = Exception) -> Callable: | |
ignore_exceptions: list = deepcopy(ignore_exceptions) if ignore_exceptions is not None else list() | |
def decorator(f: Callable) -> Callable: | |
retries_so_far: int = 0 | |
@wraps(f) | |
def wrapper(*args, **kwargs) -> Any: | |
nonlocal retries_so_far | |
while retries_so_far < count: | |
try: | |
return f(*args, **kwargs) | |
except Exception as e: | |
should_ignore = False | |
for exc in ignore_exceptions: | |
if isinstance(e, exc): | |
should_ignore = True | |
if not should_ignore: | |
retries_so_far += 1 | |
timeout: float = math.pow(retries_so_far, power) | |
print(f'\033[93mretrying in {timeout:.2f}s, retries left {count - retries_so_far:,}\033[0m') | |
time.sleep(timeout) | |
else: | |
print(f'\033[91mexception ignored\033[0m') | |
raise | |
else: | |
print('\033[91mretry limit exceeded\033[0m') | |
if raise_on_failure: | |
raise raise_on_failure() | |
return wrapper | |
return decorator |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment