diff --git a/dailyreleases/generation.py b/dailyreleases/generation.py index 7927916..9da8d56 100644 --- a/dailyreleases/generation.py +++ b/dailyreleases/generation.py @@ -113,6 +113,7 @@ def generate_post(releases: Releases) -> str: return post_str +@util.retry(attempts=3, delay=120) def generate(post=False, pm_recipients=None) -> None: logger.info("-------------------------------------------------------------------------------------------------") start_time = time.time() diff --git a/dailyreleases/util.py b/dailyreleases/util.py index 20727f5..6dda767 100644 --- a/dailyreleases/util.py +++ b/dailyreleases/util.py @@ -1,6 +1,11 @@ import difflib +import logging +import time +from functools import wraps from typing import Sequence, List +logger = logging.getLogger(__name__) + def humanize(n: int, precision=2, prefix="bin", suffix="B") -> str: """ @@ -61,3 +66,22 @@ def markdown_escape(text: str) -> str: "|": "|", } return text.translate(str.maketrans(table)) + + +def retry(attempts=3, delay=0): + """ + Retry wrapped function `attempts` times. + """ + def decorator(func): + @wraps(func) + def wrapper(*args, **kwargs): + for i in range(1, attempts+1): + try: + return func(*args, **kwargs) + except Exception as e: + logger.exception(f"{func.__name__} attempt {i}/{attempts}", exc_info=e) + if i >= attempts: + raise + time.sleep(delay) + return wrapper + return decorator