Expand description
Make retry like a built-in feature provided by Rust.
- Simple: Just like a built-in feature:
your_fn.retry(ExponentialBuilder::default()).await
. - Flexible: Supports both blocking and async functions.
- Powerful: Allows control over retry behavior such as
when
andnotify
. - Customizable: Supports custom retry strategies like exponential, constant, etc.
§Backoff
Retry in BackON requires a backoff strategy. BackON will accept a BackoffBuilder
which will generate a new Backoff
for each retry.
BackON provides several backoff implementations with reasonable defaults:
ConstantBuilder
: backoff with a constant delay, limited to a specific number of attempts.ExponentialBuilder
: backoff with an exponential delay, also supports jitter.FibonacciBuilder
: backoff with a fibonacci delay, also supports jitter.
§Sleep
Retry in BackON requires an implementation for sleeping, such an implementation
is called a Sleeper, it will implement Sleeper
or BlockingSleeper
depending
on if it is going to be used in an asynchronous context.
§Default Sleeper
Currently, BackON has 3 built-in Sleeper implementations for different environments, they are gated under their own features, which are enabled by default:
Sleeper | feature | Environment | Asynchronous |
---|---|---|---|
TokioSleeper | tokio-sleep | non-wasm32 | Yes |
[GlooTimersSleep ] | gloo-timers-sleep | wasm32 | Yes |
StdSleeper | std-blocking-sleep | all | No |
§Custom Sleeper
If you do not want to use the built-in Sleeper, you CAN provide a custom implementation, let’s implement an asynchronous dummy Sleeper that does not sleep at all. You will find it pretty similar when you implement a blocking one.
use std::time::Duration;
use backon::Sleeper;
/// A dummy `Sleeper` impl that prints then becomes ready!
struct DummySleeper;
impl Sleeper for DummySleeper {
type Sleep = std::future::Ready<()>;
fn sleep(&self, dur: Duration) -> Self::Sleep {
println!("Hello from DummySleeper!");
std::future::ready(())
}
}
§The empty Sleeper
If neither feature is enabled nor a custom implementation is provided, BackON
will fallback to the empty sleeper, in which case, a compile-time error that
PleaseEnableAFeatureOrProvideACustomSleeper needs to implement Sleeper or BlockingSleeper
will be raised to remind you to choose or bring a real Sleeper
implementation.
§Retry
For additional examples, please visit docs::examples
.
§Retry an async function
use anyhow::Result;
use backon::ExponentialBuilder;
use backon::Retryable;
use core::time::Duration;
async fn fetch() -> Result<String> {
Ok("hello, world!".to_string())
}
#[tokio::main]
async fn main() -> Result<()> {
let content = fetch
// Retry with exponential backoff
.retry(ExponentialBuilder::default())
// Sleep implementation, default to tokio::time::sleep if `tokio-sleep` has been enabled.
.sleep(tokio::time::sleep)
// When to retry
.when(|e| e.to_string() == "EOF")
// Notify when retrying
.notify(|err: &anyhow::Error, dur: Duration| {
println!("retrying {:?} after {:?}", err, dur);
})
.await?;
println!("fetch succeeded: {}", content);
Ok(())
}
§Retry a blocking function
use anyhow::Result;
use backon::BlockingRetryable;
use backon::ExponentialBuilder;
use core::time::Duration;
fn fetch() -> Result<String> {
Ok("hello, world!".to_string())
}
fn main() -> Result<()> {
let content = fetch
// Retry with exponential backoff
.retry(ExponentialBuilder::default())
// Sleep implementation, default to std::thread::sleep if `std-blocking-sleep` has been enabled.
.sleep(std::thread::sleep)
// When to retry
.when(|e| e.to_string() == "EOF")
// Notify when retrying
.notify(|err: &anyhow::Error, dur: Duration| {
println!("retrying {:?} after {:?}", err, dur);
})
.call()?;
println!("fetch succeeded: {}", content);
Ok(())
}
Re-exports§
pub use constant::ConstantBackoff;
pub use fibonacci::FibonacciBackoff;
pub use exponential::ExponentialBackoff;
Modules§
Structs§
- Retry structure generated by
BlockingRetryable
. - Retry structure generated by
BlockingRetryableWithContext
. - ConstantBuilder is used to create a [
ConstantBackoff
], providing a steady delay with a fixed number of retries. - ExponentialBuilder is used to construct an [
ExponentialBackoff
] that offers delays with exponential retries. - FibonacciBuilder is used to build a [
FibonacciBackoff
] which offers a delay with Fibonacci-based retries. - Struct generated by
Retryable
. - Retry struct generated by
RetryableWithContext
. - StdSleeper
std-blocking-sleep
The implementation ofStdSleeper
usesstd::thread::sleep
. - Tokio
Sleeper Non-WebAssembly and tokio-sleep
The default implementation ofSleeper
usestokio::time::sleep
.
Traits§
- BackoffBuilder is utilized to construct a new backoff.
- BlockingRetryable adds retry support for blocking functions.
- BlockingRetryableWithContext adds retry support for blocking functions.
- A sleeper is used sleep for a specified duration.
- Retryable will add retry support for functions that produce futures with results.
RetryableWithContext
adds retry support for functions that produce futures with results and context.- A sleeper is used to generate a future that completes after a specified duration.
Type Aliases§
- The default implementation of
Sleeper
while featurestd-blocking-sleep
enabled. - The default implementation of
Sleeper
while featuretokio-sleep
enabled.