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
//! # Circuit Breaker
//!
//! The circuit breaker pattern prevents cascading failures by monitoring
//! for failures and short-circuiting requests when the failure rate
//! exceeds a threshold. This gives downstream services time to recover.
//!
//! ## State Machine
//!
//! ```text
//! ┌─────────────────────────────────────────────┐
//! │ │
//! │ ┌──────────┐ failures >= threshold ┌─────┴───────┐
//! │ │ Closed │ ──────────────────────▶ │ Open │
//! │ │ (normal) │ │ (rejecting) │
//! │ └─────┬─────┘ └──────┬──────┘
//! │ │ │
//! │ │ successes >= threshold │ timeout elapsed
//! │ │ │
//! │ │ ┌──────────┐ │
//! │ └──────────────│ HalfOpen │◀───────────┘
//! │ │ (probing) │
//! │ └─────┬─────┘
//! │ │
//! │ any failure
//! └────────────────────────────┘
//! ```
//!
//! In **Closed** state, requests pass through normally. When failures exceed
//! the configured threshold, the circuit **trips** to Open.
//!
//! In **Open** state, requests are rejected immediately without calling the
//! operation. After `open_timeout` elapses, the circuit transitions to HalfOpen.
//!
//! In **HalfOpen** state, a limited number of probe requests are allowed through.
//! If they succeed, the circuit closes (resuming normal operation). If any fail,
//! the circuit reopens.
//!
//! The **ForcedOpen** state is a manual override — all requests are rejected
//! until `force_close()` or `reset()` is called.
//!
//! ## Modes
//!
//! The circuit breaker supports three failure-detection strategies:
//! - [`CountBased`](CircuitBreakerMode::CountBased) — trips on N consecutive failures
//! - [`SlidingWindow`](CircuitBreakerMode::SlidingWindow) — trips when failure rate ≥ 50% in a rolling time window
//! - [`Adaptive`](CircuitBreakerMode::Adaptive) — like CountBased but with exponential back-off on the open timeout
//!
//! ## Thread Safety
//!
//! All mutable state is stored on the heap via `Arc<Atomic*>` and
//! `Arc<Mutex<...>>`, making `BreakerPolicy` cheap to clone and safe to
//! share across threads. The same `BreakerPolicy` instance can be used
//! from multiple tasks concurrently.
pub use ;
pub use ;