Source code for restgdf.resilience._bounded_retry
"""Bounded-retry helper for timeout-only retries (BL-51).
Public entry point: :func:`bounded_retry_timeout`. This module centralises
the retry semantics used by :func:`restgdf.utils.getinfo._feature_count_with_timeout`
so the inline loop there can be replaced with a single delegation call when
the ``resilience`` extra is installed.
Retry contract (must match the inline fallback byte-for-byte semantically):
* Retry ONLY on timeout exceptions:
:class:`asyncio.TimeoutError`, :class:`TimeoutError`,
:class:`aiohttp.ServerTimeoutError`.
* Every other exception — in particular :class:`aiohttp.ClientConnectionError`
(R-69) and :class:`~restgdf.errors.RestgdfResponseError` — propagates
unchanged on the first attempt.
* After ``max_attempts`` timeouts, raise
:class:`~restgdf.errors.RestgdfTimeoutError` with the last timeout
exception preserved as ``__cause__``.
"""
from __future__ import annotations
import asyncio
from typing import Callable, TypeVar
from collections.abc import Awaitable
import aiohttp
import stamina
from restgdf.errors import RestgdfTimeoutError
__all__ = ["bounded_retry_timeout"]
T = TypeVar("T")
_TIMEOUT_EXCS: tuple[type[BaseException], ...] = (
asyncio.TimeoutError,
TimeoutError,
aiohttp.ServerTimeoutError,
)
[docs]
async def bounded_retry_timeout(
func: Callable[[], Awaitable[T]],
*,
max_attempts: int,
url: str,
) -> T:
"""Invoke ``func`` with bounded retry on timeout exceptions.
Parameters
----------
func:
Zero-argument awaitable factory (call produces the coroutine to run).
max_attempts:
Maximum number of attempts, identical to the inline fallback.
url:
Used only to build the ``RestgdfTimeoutError`` message on exhaustion.
"""
@stamina.retry(
on=_TIMEOUT_EXCS,
attempts=max_attempts,
timeout=None,
wait_initial=0.1,
wait_max=1.0,
wait_jitter=0.0,
wait_exp_base=2.0,
)
async def _attempt() -> T:
return await func()
try:
return await _attempt()
except _TIMEOUT_EXCS as exc:
raise RestgdfTimeoutError(
f"feature_count for {url} timed out after {max_attempts} attempts",
) from exc