Skip to content

Design notes

  • Strict envelopes: Deadline and max-attempts are enforced before each attempt; sleeps are capped to remaining deadline to avoid overruns.
  • Classification first: Policies are domain-agnostic; callers map exceptions to ErrorClass via classifiers (default or custom).
  • Per-class backoff: Strategies are looked up by class, falling back to a default; absence of a strategy is a hard error.
  • Best-effort hooks: Metric/log hooks are isolated—exceptions are swallowed so retries never break due to observability failures.
  • Deterministic jitter bounds: Built-in strategies clamp to configured maxima; property-based tests assert bounds.
  • Sync/async symmetry: RetryPolicy and AsyncRetryPolicy mirror semantics; @retry decorator auto-picks the right one.
  • Context reuse: Context managers bind hooks/operations once for batches; avoid repeating kwargs on every call.
  • Unknowns: max_unknown_attempts prevents unbounded retries on unclassified errors; deadline remains a global guardrail.