Skip to main content

execution_policy/
lib.rs

1//! `execution-policy` — closure-first reliability policies for any async operation.
2//!
3//! Wrap any async operation with retry, backoff, jitter, and per-attempt / total
4//! timeouts (circuit breaking, bounded concurrency, and retry budgets build on
5//! this foundation). The operation is a **factory** — re-invoked per attempt — so
6//! requests are freshly constructed and never need `Clone`, and `!Send`
7//! operations are accepted.
8//!
9//! ```
10//! use std::time::Duration;
11//! use execution_policy::{ExecutionPolicyBuilder, Retry};
12//!
13//! # #[tokio::main(flavor = "current_thread")]
14//! # async fn main() {
15//! let policy = ExecutionPolicyBuilder::<u32, &str>::new()
16//!     .retry(Retry::exponential().max_attempts(3))
17//!     .attempt_timeout(Duration::from_secs(2))
18//!     .build();
19//!
20//! let value = policy.run(async || Ok::<_, &str>(7u32)).await.unwrap();
21//! assert_eq!(value, 7);
22//! # }
23//! ```
24
25#![forbid(unsafe_code)]
26
27pub mod attempt;
28pub mod breaker;
29pub mod builder;
30pub mod classify;
31pub mod concurrency;
32pub mod core;
33pub mod error;
34pub mod event;
35pub mod policy;
36pub mod retry;
37
38pub(crate) mod engine;
39pub(crate) mod plan;
40
41pub use crate::attempt::Attempt;
42pub use crate::breaker::CircuitBreaker;
43pub use crate::builder::{BuildError, ExecutionPolicyBuilder};
44pub use crate::classify::{FailureClass, RetryDecision};
45pub use crate::concurrency::{ConcurrencyLimit, SaturationPolicy};
46#[cfg(feature = "tokio")]
47pub use crate::core::DefaultCore;
48pub use crate::core::{BoxFuture, Core};
49pub use crate::error::{BreakerState, ErrorContext, ExecutionError};
50pub use crate::event::Event;
51pub use crate::policy::ExecutionPolicy;
52pub use crate::retry::{Backoff, Jitter, Retry, RetryBudget};