Retry & Caching¶
Retry¶
Retry combinator with configurable backoff.
Constructor:
Retry(
inner: Combinator[T],
max_attempts: int = 3,
backoff: float = 0.0,
exponential: bool = False,
jitter: float = 0.0,
on_retry: Callable[[int, Exception | None, float], None] | None = None,
)
Parameters:
inner-- The combinator to retrymax_attempts-- Maximum number of attempts (>= 1)backoff-- Initial delay between retries in seconds (>= 0)exponential-- Whether to double the delay each attemptjitter-- Random jitter added to delay (>= 0)on_retry-- Optional callback(attempt, error, delay)called before each retry
Attributes:
last_error: Exception | None-- Error from last attempt (not thread-safe)attempts_made: int-- Number of attempts in last run (not thread-safe)
Methods:
run(ctx: T) -> tuple[bool, T]-- Execute with retriesrun_with_info(ctx: T) -> RetryResult[T]-- Thread-safe alternative returning full metadata
AsyncRetry¶
Async retry with the same interface as Retry. The on_retry callback can be sync or async.
Methods:
async run(ctx: T) -> tuple[bool, T]-- Execute with retriesasync run_with_info(ctx: T) -> RetryResult[T]-- Concurrency-safe alternative
RetryResult¶
@dataclass
class RetryResult(Generic[T]):
ok: bool
ctx: T
attempts_made: int
last_error: Exception | None
Result from Retry.run_with_info() or AsyncRetry.run_with_info().
Example:
info = fetch.run_with_info(request)
print(f"ok={info.ok}, attempts={info.attempts_made}, error={info.last_error}")
CachedPredicate¶
Predicate with result caching. Results are cached within a use_cache() scope. Created by @cached_rule.
AsyncCachedPredicate¶
Async predicate with result caching. Created by @async_cached_rule.