Skip to content

Instantly share code, notes, and snippets.

@VietThan
Created September 10, 2024 20:42
Show Gist options
  • Save VietThan/55e8081ad0a3c5bdb7dc9dfc09b481c8 to your computer and use it in GitHub Desktop.
Save VietThan/55e8081ad0a3c5bdb7dc9dfc09b481c8 to your computer and use it in GitHub Desktop.
Retry a coroutine function multiple times with a delay.
import asyncio
import logging
from typing import Any, Awaitable, Callable, TypeVar
logger = logging.getLogger(__name__)
# Define a TypeVar to capture the function's return type
R = TypeVar("R")
async def retry(
func: Callable[..., Awaitable[R]],
*args: Any,
retry_attempts: int = 3,
retry_delay: float = 2.0,
**kwargs: Any,
) -> R:
"""
Retry a coroutine function multiple times with a delay.
Args:
func: The coroutine function to retry.
retry_attempts (int): Number of times to retry the function.
retry_delay (float): Delay between retries in seconds.
Returns:
Result of the function, if successful.
Raises:
Exception: Re-raises the last caught exception if retries fail.
"""
attempt = 0
while attempt < retry_attempts:
try:
return await func(*args, **kwargs)
except Exception as e:
attempt += 1
if attempt >= retry_attempts:
raise e
logger.warning(
"Retry attempt %d/%d failed: %s. Retrying in %.1f seconds...",
attempt,
retry_attempts,
str(e),
retry_delay,
)
await asyncio.sleep(retry_delay)
# Add a return statement at the end to satisfy mypy (though this should never be reached)
assert (
False
), "Retry function should have either returned a value or raised an exception"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment