Tripwire (tripwire v0.1.0)
Copy MarkdownAn OTP-native circuit breaker library for Elixir.
Tripwire wraps target GenServers with a circuit breaker pattern:
consecutive failures trip the circuit to :open, which fast-fails
subsequent calls. After a configurable timeout, a single probe call
is allowed through to test recovery.
Usage
# Start the Registry once in your application supervisor:
{Registry, keys: :unique, name: Tripwire.Breaker.registry()}
# Start a TaskSupervisor for non-blocking forwarding:
{Task.Supervisor, name: Tripwire.TaskSupervisor}
# Start a breaker for a target:
Tripwire.start_link(target_key: :my_service, target_pid: pid)
# Call the target through the breaker:
Tripwire.call(:my_service, :some_message)States
:closed- Normal operation. Calls are forwarded to the target.:open- Circuit tripped. Calls are fast-failed.:half_open- Recovery probe. A single call is allowed through.
Infrastructure
Tripwire requires two processes running in the supervision tree:
Registrynamed:tripwire_breakerswithkeys: :unique. Maps target keys to breaker PIDs.Task.SupervisornamedTripwire.TaskSupervisor. Manages non-blocking task processes that forward calls to targets.
Example child specification:
children = [
{Registry, keys: :unique, name: Tripwire.Breaker.registry()},
{Task.Supervisor, name: Tripwire.TaskSupervisor},
{MyApp.Dependency, [name: MyApp.Dependency]},
{Tripwire, target_key: :dependency, target_pid: MyApp.Dependency}
]
Summary
Functions
Call a target GenServer through its circuit breaker.
Returns a child specification for including a Tripwire breaker in a supervision tree.
Start a circuit breaker for a target.
Functions
Call a target GenServer through its circuit breaker.
Looks up the breaker registered for target_key via
{:via, Registry, ...} addressing and forwards the call.
Parameters
target_key- Identifies the breaker, matching the:target_keyoption passed tostart_link/1.msg- Message forwarded to the target GenServer.timeout- Maximum milliseconds to wait for a response (default5000).
Returns
{:ok, result}- the target responded successfully.{:error, :circuit_open}- the circuit is open. The call was not forwarded.{:error, :breaker_not_registered}- no breaker registered for this key.{:error, :breaker_busy}- the breaker did not respond in time.{:error, {:breaker_crashed, reason}}- the breaker process crashed.
Examples
Tripwire.call(:weather, :forecast)
# => {:ok, :sunny}
Tripwire.call(:weather, :forecast, 10_000)
# => {:ok, :sunny}
Tripwire.call(:unknown, :ping)
# => {:error, :breaker_not_registered}
Returns a child specification for including a Tripwire breaker in a supervision tree.
Delegates to Tripwire.Breaker.child_spec/1. The restart type is
:permanent so a crashed breaker restarts at the :closed state
with a failure count of zero.
Options
Same options as start_link/1.
@spec start_link(keyword()) :: GenServer.on_start()
Start a circuit breaker for a target.
The breaker is registered automatically in Registry so it can be
found by call/3.
Options
:target_key- (required) unique key identifying this target. Used incall/3to route calls.:target_pid- (required) PID or registered name of the target GenServer.:threshold- consecutive failures before tripping (default5).:reset_timeout- milliseconds before:open->:half_open(default60_000).
Returns
{:ok, pid}- breaker started and registered successfully.{:error, {:already_started, pid}}- a breaker with this key is already running.{:error, reason}- startup failed.