circuit
Types
pub type ActorState {
ActorState(
circuit_state: CircuitState,
window: List(CallResult),
config: Config,
)
}
Constructors
-
ActorState( circuit_state: CircuitState, window: List(CallResult), config: Config, )
The error type returned by call/2.
CircuitOpen— the circuit is currentlyOpenand the call was blocked without executing the function.CallFailed(reason)— the circuit was not open, the function ran, but it returnedFailure(reason).
pub type CallError {
CircuitOpen
CallFailed(reason: String)
}
Constructors
-
CircuitOpen -
CallFailed(reason: String)
The result of a single call through the circuit breaker.
Pass one of these to record_result/2, or return one from the function
you pass to call/2.
Success— the call succeeded.Failure(reason)— the call failed, with a string describing why.
pub type CallResult {
Success
Failure(reason: String)
}
Constructors
-
Success -
Failure(reason: String)
An opaque handle to a running circuit breaker process.
Obtain one via start/1. Pass it to call/2, state/1, reset/1, and
record_result/2. The internals (actor Subject, message protocol) are
hidden — interact with the breaker only through the public API.
pub opaque type CircuitBreaker
Represents the three states a circuit breaker can be in.
Closed— normal operation. Calls pass through and results are tracked.Open— tripped state. All calls are blocked immediately and returnError(CircuitOpen).HalfOpen— recovery probe state. A single call is allowed through to test whether the downstream service has recovered. Success closes the circuit; failure trips it back toOpen.
pub type CircuitState {
Closed
Open
HalfOpen
}
Constructors
-
Closed -
Open -
HalfOpen
Configuration for a circuit breaker.
Use new/0 and the builder functions to construct a Config rather than
using this constructor directly.
pub type Config {
Config(
failure_threshold: Int,
window_size: Int,
reset_timeout: Int,
)
}
Constructors
-
Config( failure_threshold: Int, window_size: Int, reset_timeout: Int, )
pub type Message {
RecordResult(CallResult)
GetState(process.Subject(CircuitState))
Reset
}
Constructors
-
RecordResult(CallResult) -
GetState(process.Subject(CircuitState)) -
Reset
Values
pub fn call(
breaker: CircuitBreaker,
f: fn() -> CallResult,
) -> Result(Nil, CallError)
Runs f through the circuit breaker and records its result.
- If the circuit is
Open,fis not called andError(CircuitOpen)is returned immediately. - If the circuit is
ClosedorHalfOpen,fis called. ASuccessresult returnsOk(Nil). AFailure(reason)result returnsError(CallFailed(reason)). Either way, the result is automatically recorded against the sliding window.
Example
case circuit.call(breaker, fn() {
case fetch_user(id) {
Ok(_) -> circuit.Success
Error(_) -> circuit.Failure("fetch failed")
}
}) {
Ok(Nil) -> // call succeeded
Error(circuit.CircuitOpen) -> // blocked — try a fallback
Error(circuit.CallFailed(reason)) -> // call ran but failed
}
pub fn failure_threshold(config: Config, value: Int) -> Config
Sets the number of failures within the sliding window required to trip the
circuit from Closed to Open.
A lower value makes the breaker more sensitive. A higher value tolerates more failures before tripping.
pub fn new() -> Config
Returns a Config with sensible production defaults:
failure_threshold: 5window_size: 10reset_timeout: 30_000ms (30 seconds)
These defaults are a reasonable starting point. Tune them for your workload
using failure_threshold/2, window_size/2, and reset_timeout/2.
Example
let config =
circuit.new()
|> circuit.failure_threshold(3)
|> circuit.window_size(5)
|> circuit.reset_timeout(10_000)
pub fn record_result(
breaker: CircuitBreaker,
result: CallResult,
) -> Nil
Records a CallResult against the breaker without running a function.
Use this when you are managing the call yourself and just want to inform
the breaker of the outcome. For the common case of wrapping a function,
prefer call/2 instead.
pub fn reset(breaker: CircuitBreaker) -> Nil
Manually resets the breaker to Closed and clears the sliding window.
Useful in tests or admin tooling. In normal operation the breaker manages its own state — you should rarely need to call this directly.
pub fn reset_timeout(config: Config, value: Int) -> Config
Sets how long (in milliseconds) the circuit stays Open before
transitioning to HalfOpen to probe for recovery.
A shorter timeout means faster recovery attempts. A longer timeout gives the downstream service more time to recover before being probed.
pub fn start(
config: Config,
) -> Result(CircuitBreaker, actor.StartError)
Starts a new circuit breaker process with the given Config.
Returns Ok(CircuitBreaker) on success, or Error(actor.StartError) if
the underlying OTP actor fails to start.
Example
let assert Ok(breaker) =
circuit.new()
|> circuit.failure_threshold(5)
|> circuit.start()
pub fn state(breaker: CircuitBreaker) -> CircuitState
Returns the current CircuitState of the breaker (Closed, Open, or HalfOpen).
This is a synchronous call to the actor — it blocks briefly until the actor responds.
pub fn transition(
state: CircuitState,
result: CallResult,
failures: Int,
config: Config,
) -> CircuitState
pub fn window_size(config: Config, value: Int) -> Config
Sets the size of the sliding window — the number of most recent calls that are tracked when calculating the failure rate.
For example, a window_size of 10 means only the last 10 call results are
considered. Older results are discarded automatically.