Created
March 25, 2025 11:43
-
-
Save shortthirdman/ab07276bd5cef9ae43130429e733ce2d to your computer and use it in GitHub Desktop.
Async Retry Decorator
This file contains hidden or 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 functools | |
import time | |
import random | |
import asyncio | |
def async_retry(max_retries=3, start_delay=2, backoff_factor=2, exceptions=(Exception,)): | |
"""Retry decorator for async functions with exponential backoff.""" | |
def decorator(func): | |
@functools.wraps(func) | |
async def wrapper(*args, **kwargs): | |
delay = start_delay | |
last_exception = None | |
for attempt in range(1, max_retries + 1): | |
try: | |
return await func(*args, **kwargs) | |
except exceptions as e: | |
last_exception = e | |
# Add jitter to delay to prevent thundering herd problem | |
jitter = random.uniform(0.8, 1.2) | |
sleep_time = delay * jitter | |
print(f"Attempt {attempt} failed: {e}. Retrying in {sleep_time:.2f}s") | |
await asyncio.sleep(sleep_time) | |
# Increase delay for next attempt | |
delay *= backoff_factor | |
# If we get here, all retries failed | |
raise last_exception | |
return wrapper | |
return decorator | |
# Usage | |
@async_retry(max_retries=5, exceptions=(aiohttp.ClientError, asyncio.TimeoutError)) | |
async def fetch_url(session, url): | |
async with session.get(url, timeout=30) as response: | |
return await response.text() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment