| 123456789101112131415161718192021222324252627282930313233343536373839 |
- import logging
- import time
- from typing import Callable, TypeVar
- logger = logging.getLogger(__name__)
- T = TypeVar("T")
- def retry_on_failure(
- fn: Callable[[], T],
- *,
- max_retries: int = 3,
- backoff_base: float = 2.0,
- task_name: str = "",
- ) -> T:
- """在失败时使用指数退避进行重试,仅用于任务提交阶段。
- fn 应当在提交不成功时抛出异常,所有重试耗尽后将抛出最后一次的异常。
- """
- last_exc: Exception | None = None
- for attempt in range(1, max_retries + 1):
- try:
- return fn()
- except Exception as e:
- last_exc = e
- if attempt < max_retries:
- wait = backoff_base ** attempt
- logger.warning(
- "[%s] Submit attempt %d/%d failed: %s, retrying in %.1fs …",
- task_name, attempt, max_retries, e, wait,
- )
- time.sleep(wait)
- else:
- logger.error(
- "[%s] All %d submit attempts exhausted, last error: %s",
- task_name, max_retries, e,
- )
- raise last_exc # type: ignore[misc]
|