use std::ops::ControlFlow;
use std::time::{Duration, Instant};
use sisyphus::{retry_sync, ExponentialBackoff, PolicyExt, RetryError};
fn flaky_connect(attempt: u32) -> Result<&'static str, &'static str> {
if attempt < 4 {
Err("connection refused")
} else {
Ok("connected")
}
}
fn main() {
let policy = ExponentialBackoff::new(Duration::from_millis(50), 2.0)
.with_max_delay(Duration::from_secs(1))
.max_attempts(6);
let mut attempt = 0u32;
let started = Instant::now();
let result: Result<&str, RetryError<&str>> = retry_sync(
policy,
|| {
attempt += 1;
match flaky_connect(attempt) {
Ok(ok) => ControlFlow::Break(ok),
Err(transient) => {
println!("attempt {attempt} failed: {transient}");
ControlFlow::Continue(transient)
}
}
},
|delay| {
println!(" backing off for {delay:?}");
std::thread::sleep(delay);
},
);
match result {
Ok(msg) => println!(
"success after {attempt} attempts in {:?}: {msg}",
started.elapsed()
),
Err(RetryError::Exhausted(last)) => {
println!("gave up after {attempt} attempts; last error: {last}");
}
}
}