Skip to main content
retry adds per-attempt timeout, retry/backoff, and optional semaphore-based concurrency control around async and sync callables. It works for ordinary functions without creating an EventBus. Sync callables stay sync and block synchronously for retry sleeps and semaphore waits. Async callables stay async and await retry sleeps and semaphore waits. Supported callable forms:
  • Python: sync and async functions, methods, and lambdas via @retry(...) or retry(...)(fn).
  • TypeScript: sync and async functions and arrow functions via retry(...)(fn), plus sync and async class methods via @retry(...).
  • Rust: sync and async free functions and methods via abxbus::retry!; call those retried functions from Rust closures such as EventBus handlers.
  • Go: retry is not implemented yet.

Signature

Options

Example: Standalone function

Example: Inline wrapper

Example: Decorated class method

Behavior

  • Semaphore acquisition happens once per call, then all retry attempts run within that acquired slot.
  • Backoff delay per retry is: retry_after * retry_backoff_factor^(attempt - 1).
  • Retries stop immediately when the thrown error does not match retry_on_errors.
  • Bus/event timeouts act as outer execution budgets; retry.timeout is per-attempt.
  • Sync wrappers return synchronously and block synchronously for retry sleeps and semaphore waits.
  • Rust retry functions return Result<T, E> where E: From<abxbus::retry::RetryError>.

Runtime differences

  • Python and TypeScript both support multiprocess, global, class, and instance.
  • Rust supports multiprocess, global, class, and instance through abxbus::retry!.
  • Go does not include retry yet.
  • TypeScript uses async-context re-entrancy tracking in Node/Bun to avoid same-semaphore nested deadlocks.
  • retry_on_errors matching differs slightly:
    • Python: exception classes or compiled regex patterns (matched against "ErrorClass: message").
    • TypeScript: error constructors, error-name strings, or regex patterns.
    • Rust: typed predicate function via retry_if = should_retry.