""" Retry policy implementation """ import time from typing import Callable, Any, Optional from functools import wraps from core_engine.common.config import Config from core_engine.common.logger import logger def retry_with_backoff( max_retries: int = None, backoff_base: float = None, retryable_exceptions: tuple = None ): """ Decorator for retrying function calls with exponential backoff Args: max_retries: Maximum number of retries (default from config) backoff_base: Base delay in seconds (default from config) retryable_exceptions: Tuple of exceptions to retry on """ max_retries = max_retries or Config.MAX_RETRIES backoff_base = backoff_base or Config.RETRY_BACKOFF_BASE retryable_exceptions = retryable_exceptions or (Exception,) def decorator(func: Callable) -> Callable: @wraps(func) def wrapper(*args, **kwargs) -> Any: last_exception = None for attempt in range(max_retries + 1): try: return func(*args, **kwargs) except retryable_exceptions as e: last_exception = e if attempt < max_retries: delay = backoff_base * (2 ** attempt) logger.warning( f"Retry attempt {attempt + 1}/{max_retries} for {func.__name__}", error=e, delay=delay ) time.sleep(delay) else: logger.error( f"Max retries exceeded for {func.__name__}", error=e ) raise if last_exception: raise last_exception return wrapper return decorator