circuit
Prevent cascading failures in your Gleam applications. Circuit breaker pattern with sliding window tracking, OTP-supervised state, and support for both Erlang and JavaScript targets.
What is a circuit breaker?
When a downstream service (an API, a database, a queue) starts failing, naively retrying every call makes things worse — you flood a struggling service and slow your whole application down in the process.
A circuit breaker wraps those calls and watches for failures. After enough failures it trips open, blocking calls entirely and returning an error instantly instead of waiting. After a cooldown it allows a single probe call through to check if the service has recovered. If it has, the circuit closes again and normal traffic resumes.
Three states:
| State | Behaviour |
|---|---|
Closed | Normal. Calls pass through, results are tracked. |
Open | Tripped. All calls blocked, Error(CircuitOpen) returned immediately. |
HalfOpen | Recovery probe. One call allowed through — success closes, failure re-opens. |
Installation
gleam add circuit@1
Quick Start
import circuit
pub fn main() {
// 1. Configure and start a breaker
let assert Ok(breaker) =
circuit.new()
|> circuit.failure_threshold(5) // trip after 5 failures
|> circuit.window_size(10) // track the last 10 calls
|> circuit.reset_timeout(30_000) // wait 30s before probing
|> circuit.start()
// 2. Wrap your calls
case circuit.call(breaker, fn() {
case fetch_user(42) {
Ok(_user) -> circuit.Success
Error(_) -> circuit.Failure("fetch_user failed")
}
}) {
Ok(Nil) -> // call succeeded
Error(circuit.CircuitOpen) -> // blocked — use a fallback or return cached data
Error(circuit.CallFailed(reason)) -> // call ran but failed
}
}
That’s it. The breaker tracks results, manages state transitions, and runs as a supervised OTP process — no global state, no ETS tables.
API
| Function | Description |
|---|---|
new() | Create a Config with default values |
failure_threshold(config, n) | Set failures required to trip (default: 5) |
window_size(config, n) | Set sliding window size (default: 10) |
reset_timeout(config, ms) | Set cooldown before HalfOpen probe (default: 30 000ms) |
start(config) | Spawn the breaker actor, returns Result(CircuitBreaker, _) |
call(breaker, f) | Run f through the breaker, auto-records result |
record_result(breaker, result) | Manually record a Success or Failure |
state(breaker) | Read the current CircuitState |
reset(breaker) | Manually reset to Closed and clear the window |
Full documentation: hexdocs.pm/circuit
Development
gleam test # run the test suite
gleam build # compile and check
Made with ♥ using Gleam