pub struct CircuitBreaker { /* private fields */ }Expand description
A circuit breaker that prevents cascading failures by stopping requests to a failing downstream service.
§State machine
Closed ──(failures ≥ threshold)──► Open
▲ │
│ │ (timeout elapsed)
│ ▼
└──(success_rate ≥ threshold)── HalfOpen- Closed — normal operation; all requests flow through.
- Open — all requests are rejected immediately with
CircuitBreakerError::Openwithout calling the wrapped operation. - HalfOpen — a single probe request is allowed; on success the circuit closes; on failure it reopens.
§Cloning
CircuitBreaker is Clone + Send + Sync. All clones share the same
underlying Arc<RwLock<CircuitState>>.
§Examples
use std::time::Duration;
use tokio_prompt_orchestrator::enhanced::CircuitBreaker;
use tokio_prompt_orchestrator::enhanced::circuit_breaker::CircuitBreakerError;
let cb = CircuitBreaker::new(5, 0.8, Duration::from_secs(30));
let result = cb.call(|| async {
reqwest::get("https://api.example.com/infer")
.await
.map_err(|e| e.to_string())
}).await;
match result {
Ok(resp) => { /* handle response */ }
Err(CircuitBreakerError::Open) => { /* fail fast */ }
Err(CircuitBreakerError::Failed(e)) => { /* handle error */ }
}Implementations§
Source§impl CircuitBreaker
impl CircuitBreaker
Sourcepub fn new(
failure_threshold: usize,
success_threshold: f64,
timeout: Duration,
) -> Self
pub fn new( failure_threshold: usize, success_threshold: f64, timeout: Duration, ) -> Self
Create a new CircuitBreaker in the Closed state.
§Arguments
failure_threshold— Number of consecutive failures required to open the circuit. A value of1opens immediately on the first error.success_threshold— Required success rate (0.0..=1.0) over the recent-results window before the circuit closes fromHalfOpen. Typical values:0.8(80 %) or1.0(100 %).timeout— How long to stay in theOpenstate before transitioning toHalfOpenand allowing one probe request through.
The default rolling-window size is 100 results. Use
with_window_size to customise it.
§Examples
use std::time::Duration;
use tokio_prompt_orchestrator::enhanced::CircuitBreaker;
// Open after 5 failures; require 80 % success rate to close; probe after 60 s.
let cb = CircuitBreaker::new(5, 0.8, Duration::from_secs(60));Sourcepub fn with_window_size(self, size: usize) -> Self
pub fn with_window_size(self, size: usize) -> Self
Set the rolling-window size used to calculate the success rate.
The window keeps the most recent size call outcomes. A smaller window
reacts faster to bursts of failures but is more sensitive to noise. The
default is 100.
§Examples
use std::time::Duration;
use tokio_prompt_orchestrator::enhanced::CircuitBreaker;
// Tighter window — reacts faster to short failure bursts.
let cb = CircuitBreaker::new(5, 0.8, Duration::from_secs(30))
.with_window_size(20);§Panics
This function does not panic.
Sourcepub async fn call<F, Fut, T, E>(
&self,
f: F,
) -> Result<T, CircuitBreakerError<E>>
pub async fn call<F, Fut, T, E>( &self, f: F, ) -> Result<T, CircuitBreakerError<E>>
Execute a fallible async operation through the circuit breaker.
If the circuit is Open the operation is not called and
Err(CircuitBreakerError::Open) is returned immediately.
Otherwise the closure is invoked; its Ok/Err outcome is recorded
and may cause a state transition.
§Arguments
f— AFnOncethat returns aFuture<Output = Result<T, E>>. The closure is called at most once percallinvocation.
§Returns
Ok(value)— operation succeeded.Err(CircuitBreakerError::Open)— circuit is open; request rejected.Err(CircuitBreakerError::Failed(e))— operation returnedErr(e).
§Examples
use std::time::Duration;
use tokio_prompt_orchestrator::enhanced::CircuitBreaker;
use tokio_prompt_orchestrator::enhanced::circuit_breaker::CircuitBreakerError;
let cb = CircuitBreaker::new(3, 0.8, Duration::from_secs(10));
let result = cb.call(|| async { Ok::<_, String>("ok") }).await;
assert!(matches!(result, Ok("ok")));Sourcepub fn is_closed_sync(&self) -> bool
pub fn is_closed_sync(&self) -> bool
Returns true if the circuit is currently closed (normal operation).
This is a best-effort synchronous read — use status() for authoritative state.
Sourcepub fn is_open_sync(&self) -> bool
pub fn is_open_sync(&self) -> bool
Returns true if the circuit is currently open (rejecting requests).
Sourcepub fn is_half_open_sync(&self) -> bool
pub fn is_half_open_sync(&self) -> bool
Returns true if the circuit is in half-open state (testing recovery).
Sourcepub async fn status(&self) -> CircuitStatus
pub async fn status(&self) -> CircuitStatus
Get current circuit status
Sourcepub async fn stats(&self) -> CircuitBreakerStats
pub async fn stats(&self) -> CircuitBreakerStats
Get circuit breaker statistics
Trait Implementations§
Source§impl Clone for CircuitBreaker
impl Clone for CircuitBreaker
Source§fn clone(&self) -> CircuitBreaker
fn clone(&self) -> CircuitBreaker
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreAuto Trait Implementations§
impl !RefUnwindSafe for CircuitBreaker
impl !UnwindSafe for CircuitBreaker
impl Freeze for CircuitBreaker
impl Send for CircuitBreaker
impl Sync for CircuitBreaker
impl Unpin for CircuitBreaker
impl UnsafeUnpin for CircuitBreaker
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
§impl<T> FutureExt for T
impl<T> FutureExt for T
§fn with_context(self, otel_cx: Context) -> WithContext<Self>
fn with_context(self, otel_cx: Context) -> WithContext<Self>
§fn with_current_context(self) -> WithContext<Self>
fn with_current_context(self) -> WithContext<Self>
§impl<T> Instrument for T
impl<T> Instrument for T
§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoRequest<T> for T
impl<T> IntoRequest<T> for T
Source§fn into_request(self) -> Request<T>
fn into_request(self) -> Request<T>
T in a tonic::Request