-module(livery_client_circuit). -moduledoc """ Client layer: a circuit breaker. Tracks the recent failure ratio for a named target. While the circuit is closed, requests pass and outcomes are tallied over a tumbling `window`; once the failure ratio reaches `trip`, the circuit opens and further requests fail fast with `{error, circuit_open}`. After `cooldown` ms the breaker half-opens to let one probe through, closing again on success or re-opening on failure. Add it with `livery_client:circuit_breaker/1`. `Opts`: `name` (required), `window` (default 20), `trip` (default 0.5), `cooldown` ms (default 5000). """. -export([call/3]). -spec call(livery_client:request(), livery_client:next(), map()) -> {ok, livery_client:response()} | {error, term()}. call(Req, Next, Opts) -> Name = maps:get(name, Opts), Cooldown = maps:get(cooldown, Opts, 5000), case livery_client_circuit_store:allow(Name, Cooldown) of deny -> {error, circuit_open}; allow -> Result = Next(Req), Window = maps:get(window, Opts, 20), Trip = maps:get(trip, Opts, 0.5), livery_client_circuit_store:record(Name, outcome(Result), Window, Trip), Result end. outcome({ok, _Response}) -> ok; outcome({error, _Reason}) -> err.