pub struct Retry<E = BoxError> { /* private fields */ }Expand description
Retry policy and executor facade bound to an operation error type.
The generic parameter E is the caller’s operation error type. Cloning a
retry policy shares all registered functors through reference-counted
rs-function wrappers.
§Architecture
Retry is the public facade of the retry engine. It owns two stable pieces
of state:
RetryOptions, which describes the policy: attempt limits, elapsed budgets, backoff, retry-after handling, per-attempt timeout, and worker-cancellation grace.RetryEvents, the internal dispatcher for listener callbacks and retry-after hints.
The facade deliberately contains no retry loop logic. Each public execution method creates a mode-specific runner and delegates the real control flow:
Retry::runusesRetryRunnerand executes the caller’s closure on the current thread.Retry::run_async(requires thetokiofeature) usesAsyncRetryRunnerand executes each future on the current Tokio task.Retry::run_in_workerusesWorkerRetryRunnerand executes each attempt inside a worker thread.
Those runners all follow the same conceptual pipeline. They adapt the
caller’s operation into an internal attempt object, keep a
RetryFlowState, fire lifecycle events, call the operation once per
attempt, and pass failures to RetryFailureHandler to decide whether to
sleep and retry or return a terminal RetryError. The mode-specific runner
owns only the execution mechanics that differ by mode: blocking sleep,
Tokio timeout, worker-thread panic capture, and cooperative cancellation.
This split keeps the public API small while keeping timeout and concurrency
details out of the Retry facade.
Implementations§
Source§impl<E> Retry<E>
impl<E> Retry<E>
Sourcepub fn builder() -> RetryBuilder<E>
pub fn builder() -> RetryBuilder<E>
Sourcepub fn from_options(options: RetryOptions) -> Result<Self, RetryConfigError>
pub fn from_options(options: RetryOptions) -> Result<Self, RetryConfigError>
Creates a retry policy from options.
§Parameters
options: Retry options to validate and install.
§Returns
A retry policy using the default listener set.
§Errors
Returns RetryConfigError if the options are invalid.
Sourcepub fn options(&self) -> &RetryOptions
pub fn options(&self) -> &RetryOptions
Sourcepub fn run<T, F>(&self, operation: F) -> Result<T, RetryError<E>>
pub fn run<T, F>(&self, operation: F) -> Result<T, RetryError<E>>
Runs a synchronous operation with retry.
This method is the same-thread execution path. The call flow is:
- Create a
RetryRunnerthat borrows this retry policy. - Wrap
operationin a value-capturing internal adapter so the retry loop can work with a type-erasedResult<(), AttemptFailure<E>>while preserving the successfulTvalue. - Reject configured
attempt_timeout, because a same-thread closure cannot be interrupted safely once it starts running. - For each attempt, update
RetryFlowState, firebefore_attempt, call the closure directly on the current thread, record elapsed operation time, and fire success or failure events. - On failure, let
RetryFailureHandlerapply retry limits, error predicates, retry-after hints, elapsed budgets, and backoff. If it chooses retry, sleep withstd::thread::sleepand start the next attempt; otherwise return the producedRetryError.
§Parameters
operation: Operation called once per attempt until it succeeds or the retry flow stops.
§Returns
Ok(T) with the operation value, or RetryError when retrying stops.
§Panics
Propagates operation panics and listener panics unless listener panic isolation is enabled.
§Blocking
Blocks the current thread with std::thread::sleep between attempts when
a non-zero retry delay is selected.
§Elapsed Budget
max_operation_elapsed counts only user operation execution time.
max_total_elapsed counts monotonic retry-flow time, including
operation execution, retry sleep, retry-after sleep, and retry
control-path listener time. This synchronous mode cannot interrupt an
already-running operation; it checks budgets before attempts and after
failed attempts. If attempt_timeout is configured, this method returns
crate::RetryErrorReason::UnsupportedOperation because timeout
enforcement requires worker-thread or async execution.
Sourcepub async fn run_async<T, F, Fut>(
&self,
operation: F,
) -> Result<T, RetryError<E>>
pub async fn run_async<T, F, Fut>( &self, operation: F, ) -> Result<T, RetryError<E>>
Runs an asynchronous operation with retry.
This method is the Tokio execution path. The call flow is:
- Create an
AsyncRetryRunnerthat borrows this retry policy. - Wrap
operationin an async value-capturing adapter. The operation is a factory: it must create a fresh future for every attempt because a Rust future cannot be polled again after it completes. - Before each attempt, compute the effective timeout from the configured
attempt_timeout, remainingmax_operation_elapsed, and remainingmax_total_elapsed; the shortest available budget wins. - Fire
before_attempt, recompute budgets in case listeners consumed total elapsed time, then await the attempt future. If an effective timeout exists, the future is wrapped intokio::time::timeoutand dropped when the timer fires. - Record elapsed operation time, fire success events, or route the
failure through elapsed-budget classification and
RetryFailureHandler. Retry delays usetokio::time::sleep; terminal decisions returnRetryError.
§Parameters
operation: Factory returning a fresh future for each attempt.
§Returns
Ok(T) with the operation value, or RetryError when retrying stops.
§Panics
Propagates operation panics from the current async task. They are not
converted to crate::AttemptFailure::Panic because run_async does
not create an isolation boundary. Listener panics are propagated unless
listener panic isolation is enabled. Tokio may panic if timer APIs are
used outside a runtime with a time driver.
§Elapsed Budget
max_operation_elapsed counts only user operation execution time.
max_total_elapsed counts monotonic retry-flow time. Async attempts use
the shortest of configured attempt timeout, remaining
max-operation-elapsed budget, and remaining max-total-elapsed budget as
their effective timeout.
Sourcepub fn run_in_worker<T, F>(&self, operation: F) -> Result<T, RetryError<E>>
pub fn run_in_worker<T, F>(&self, operation: F) -> Result<T, RetryError<E>>
Runs a blocking operation with retry inside worker-thread attempts.
This method is the blocking-isolation execution path. The call flow is:
- Create a
WorkerRetryRunnerthat borrows this retry policy. - Wrap the operation in a shared blocking adapter. The adapter stores
the successful
Tvalue outside the type-erased retry loop. - For each attempt, compute the effective timeout from configured
attempt_timeoutand remaining elapsed budgets, firebefore_attempt, then spawn one worker-thread attempt throughWorkerAttemptExecutor. - The worker receives an
AttemptCancelToken. If the effective timeout expires, the runner marks that token as cancelled and waits up tocrate::RetryOptions::worker_cancel_gracefor cooperative exit. - Worker panics become
crate::AttemptFailure::Panic, worker-spawn failures becomecrate::AttemptFailure::Executor, and timeout or application failures are passed through the normal retry policy. - The runner refuses to start another worker while a timed-out worker is
still running, because that would create concurrent attempts for one
retry flow. That condition returns
crate::RetryErrorReason::WorkerStillRunning.
Each attempt runs on a worker thread. Worker panics are captured as
crate::AttemptFailure::Panic. Worker-spawn failures are reported as
crate::AttemptFailure::Executor. If the effective timeout expires,
the retry executor stops waiting and marks the attempt’s
AttemptCancelToken as cancelled. It then waits up to
crate::RetryOptions::worker_cancel_grace for the worker to exit.
Configured attempt-timeout expirations continue according to
crate::AttemptTimeoutPolicy only when the worker exits within that
grace period; otherwise the retry flow stops with
crate::RetryErrorReason::WorkerStillRunning. Elapsed-budget
expirations stop with
crate::RetryErrorReason::MaxOperationElapsedExceeded or
crate::RetryErrorReason::MaxTotalElapsedExceeded.
§Parameters
operation: Thread-safe operation called once per attempt. It receives a cooperative cancellation token for that attempt.
§Returns
Ok(T) with the operation value, or RetryError when retrying stops.
§Panics
Does not propagate operation panics. Listener panic behavior follows this retry policy’s listener isolation setting.
§Blocking
Blocks the current thread while waiting for each worker result or timeout and while sleeping between retry attempts.
§Elapsed Budget
max_operation_elapsed counts only user operation execution time.
max_total_elapsed counts monotonic retry-flow time. Worker attempts use
the shortest of configured attempt timeout, remaining
max-operation-elapsed budget, and remaining max-total-elapsed budget as
their effective timeout.
Trait Implementations§
Auto Trait Implementations§
impl<E> Freeze for Retry<E>
impl<E = Box<dyn Error + Send + Sync>> !RefUnwindSafe for Retry<E>
impl<E> Send for Retry<E>
impl<E> Sync for Retry<E>
impl<E> Unpin for Retry<E>
impl<E> UnsafeUnpin for Retry<E>
impl<E = Box<dyn Error + Send + Sync>> !UnwindSafe for Retry<E>
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T, D> IntoConfigDefault<T> for Dwhere
D: IntoValueDefault<T>,
impl<T, D> IntoConfigDefault<T> for Dwhere
D: IntoValueDefault<T>,
Source§fn into_config_default(self) -> T
fn into_config_default(self) -> T
T.