1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
//! # mettle
//!
//! A resilience toolkit for Rust: composable, testable primitives for handling failure, so you
//! don't hand-roll retry-and-backoff logic in every project.
//!
//! Available now: `retry()` (async) and `blocking::retry()` (sync), both with configurable
//! backoff. Timeout and circuit breaking are planned.
//!
//! # Quickstart
//!
//! Retry an async operation with sensible defaults (exponential backoff, up to 3 retries):
//!
//! ```no_run
//! # #[cfg(feature = "async")]
//! # async fn demo() -> Result<(), Box<dyn std::error::Error>> {
//! use mettle::retry;
//!
//! let value = retry(|| async { fetch().await }).await?;
//! # let _ = value;
//! # Ok(())
//! # }
//! # #[cfg(feature = "async")]
//! # async fn fetch() -> Result<u32, std::io::Error> { Ok(1) }
//! ```
//!
//! Override the backoff, clock, retry predicate (`.when`), or time budget (`.max_elapsed`) with
//! the builder methods, then `.await`. No async runtime? The blocking twin is identical but ends
//! in `.call()` instead of `.await`.
//!
//! # Observability
//!
//! Every retry emits a [`tracing`](https://docs.rs/tracing) event on target `mettle::retry` at
//! `WARN`, carrying the `attempt` number, `delay_ms`, and the `error`. Install any subscriber to
//! see them, filter with `RUST_LOG=mettle::retry=warn`, or silence with `RUST_LOG=mettle=off`.
compile_error!;
pub use ;
pub use Clock;
pub use retry;