In this lesson, you will learn how to implement the Circuit Breaker pattern to protect your system from cascading failures by automatically halting requests to a service that is consistently erroring.
The Logic of the Breaker
Imagine your application is calling a remote database that is currently failing. If you keep retrying every request, you waste CPU cycles and potentially overwhelm the service further. A Circuit Breaker acts as a state machine with three modes:
- Closed: Requests flow normally. Failures are tracked.
- Open: Requests are blocked immediately. The system is "tripped," allowing the downstream service to recover.
- Half-Open: A limited number of test requests are allowed. If they succeed, the breaker resets to Closed.
Implementation Pattern
In Rust, we typically model this using an enum for the state and a struct to track failure counts. Because this component is stateful and often shared across threads, you will frequently wrap it in an Arc<Mutex<T>>.
enum State { Closed, Open(Instant), HalfOpen }
struct CircuitBreaker {
state: State,
failure_count: u32,
threshold: u32,
}
impl CircuitBreaker {
fn call<F, T, E>(&mut self, action: F) -> Result<T, E>
where F: FnOnce() -> Result<T, E>
{
if let State::Open(until) = self.state {
if Instant::now() < until {
return Err(CustomError::CircuitOpen);
}
self.state = State::HalfOpen;
}
match action() {
Ok(val) => {
self.failure_count = 0;
self.state = State::Closed;
Ok(val)
}
Err(e) => {
self.failure_count += 1;
if self.failure_count >= self.threshold {
self.state = State::Open(Instant::now() + Duration::from_secs(30));
}
Err(e)
}
}
}
}
By decoupling the execution logic from the state tracking, the circuit breaker allows your application to "fail fast" when it knows a downstream dependency is unhealthy. This pattern is essential for building distributed systems that respect the stability of the services they rely on.
Key Takeaway: The Circuit Breaker prevents resource exhaustion by switching from active execution to a fail-fast state once a failure threshold is reached.