use core::time::Duration;
use relentless::{RetryError, retry_async, sleep, stop, wait};
use tokio_util::sync::CancellationToken;
async fn flaky_network_call(attempt: u32) -> Result<String, String> {
tokio::time::sleep(Duration::from_millis(40)).await; Err(format!("attempt {attempt}: connection refused"))
}
#[tokio::main]
async fn main() {
let result = tokio::time::timeout(
Duration::from_millis(120),
retry_async(|state| flaky_network_call(state.attempt))
.stop(stop::attempts(10))
.wait(wait::fixed(Duration::from_millis(50)))
.sleep(sleep::tokio()),
)
.await;
match result {
Ok(Ok(val)) => println!("pattern 1 — success: {val}"),
Ok(Err(RetryError::Exhausted { last })) => {
println!("pattern 1 — retries exhausted, last: {last:?}");
}
Ok(Err(e)) => println!("pattern 1 — rejected: {e:?}"),
Err(_elapsed) => println!("pattern 1 — deadline exceeded (cancelled mid-sleep)"),
}
let token = CancellationToken::new();
tokio::spawn({
let token = token.clone();
async move {
tokio::time::sleep(Duration::from_millis(120)).await;
token.cancel(); }
});
tokio::select! {
result = retry_async(|state| flaky_network_call(state.attempt))
.stop(stop::attempts(10))
.wait(wait::fixed(Duration::from_millis(50)))
.sleep(sleep::tokio()) =>
{
match result {
Ok(val) => println!("pattern 2 — success: {val}"),
Err(e) => println!("pattern 2 — retries exhausted: {e:?}"),
}
}
() = token.cancelled() => {
println!("pattern 2 — cancellation token fired (cancelled mid-sleep)");
}
}
let (shutdown_tx, shutdown_rx) = tokio::sync::oneshot::channel::<()>();
tokio::spawn(async move {
tokio::time::sleep(Duration::from_millis(120)).await;
let _ = shutdown_tx.send(());
});
tokio::select! {
result = retry_async(|state| flaky_network_call(state.attempt))
.stop(stop::attempts(10))
.wait(wait::fixed(Duration::from_millis(50)))
.sleep(sleep::tokio()) =>
{
match result {
Ok(val) => println!("pattern 3 — success: {val}"),
Err(e) => println!("pattern 3 — retries exhausted: {e:?}"),
}
}
_ = shutdown_rx => {
println!("pattern 3 — shutdown signal received (cancelled mid-sleep)");
}
}
}