Expand description
Automatic retry/backoff middleware for the trillium HTTP client.
RetryHandler is a ClientHandler that re-issues a request when it fails in a way that
is worth retrying — a transport-level error (connection refused, reset, timeout) or a
retryable response status (429, 503 by default) — spacing attempts out with a configurable
backoff schedule and honoring a server-advertised Retry-After.
use std::time::Duration;
use trillium_client::Client;
use trillium_client_retry::RetryHandler;
use trillium_testing::client_config;
let client = Client::new(client_config()).with_handler(
RetryHandler::default()
.with_exponential_backoff(Duration::from_millis(100))
.with_max_attempts(5),
);§Behavior
Each attempt runs as a full client-handler cycle (queued via set_followup), so other
handlers — loggers, conn-id, metrics — observe every attempt. Place RetryHandler as the
outermost handler so those observers see each attempt before the backoff sleep.
§What is retried
By default, retries are limited to idempotent methods (GET, HEAD, PUT, DELETE, OPTIONS,
TRACE). Within that gate, a request is retried when it fails with a transport error or returns
a status in the configured set. Adjust with with_all_methods, with_statuses, and
with_transport_errors, or replace the whole decision with retry_when /
with_decision.
§Request bodies
A request body is replayed only if it can be cloned (static bodies — Vec<u8>, String,
&'static str, etc.). A streaming (one-shot) body cannot be replayed, so a request carrying
one is not retried; its result is surfaced as-is.
§Limits
Retrying stops at whichever comes first: with_max_attempts total attempts, or the
with_max_elapsed wall-clock budget. The budget is a hard ceiling — each attempt’s timeout
is clamped to the time remaining, so a single slow attempt can’t overrun it. (The very first
attempt uses the client’s own timeout, since the budget is established once the request is in
flight; keep max_elapsed at least as large as the client timeout.)
§Retry-After
When honor_retry_after is set (the default) and the
response carries a Retry-After header in delta-seconds form, that delay takes precedence
over the computed backoff (clamped by with_max_retry_after if set, and always by the
elapsed budget). Retry-After HTTP-date values are not yet parsed and fall back to the
computed backoff.
Structs§
- Retry
Handler - A
ClientHandlerthat automatically retries failed requests with backoff.