View Source TripSwitch (TripSwitch v0.1.3)
TripSwitch is an Elixir implementation of a circuit breaker. The circuit breaker is a popular pattern in softwares that depends on various components/services to keep running.
This library allows you wrap calls (signals) to remote calls in a trip switch. The switch monitors each invocation and records failures, the trip switch gets broken once the recorded failures reaches or surpasses the specified threshold.
signal
Signal
A signal is simple a function that gets invoked. The state of the trip switch gets
updated based on the result of this signal, see TripSwitch.Breaker.signal/0
.
examples
Examples
iex> TripSwitch.send(id, fn -> {:ok, :good} end)
{:ok, :good}
iex> TripSwitch.send(id, fn -> {:break, :good} end) # record this signal as a failure
{:ok, :good}
Note that a switch only stops invoking a signal after the failure threshold have been
reached. In this case, the switch keeps is considered broken
until it's repaired.
repairs
Repairs
It's obvious you are asking yourself what you should do when a trip switch gets broken. This
library have a concept called Repair. What this means is that a switch is sent for repair
automatically once it gets broken. Not all trip switches are considered fixable, you
need to specify a repair_time
(in milliseconds) when the trip switch is created
else you need to manually fix (reset) the trip switch whenever it gets broken.
thresholds
Thresholds
For a trip switch to function correctly, a threshold is needed to be specified. This allows us to define the capacity/expectation of the trip switch. The threshold is specified as a float value, usually between 0 and 1 (ex. 0.2566 or 0.13 and so on).
Simply, a threshold is the percentage of bad signals a trip switch receives before it gets broken and sent for repair.
usage
Usage
To create a trip switch you need to add it to your supervision tree:
children = [{TripSwitch, name: :switch, threshold: 0.5}]
Supervisor.start_link(children, opts)
It supports following options:
:name
- this will be used as the id for the switch:threshold
- the maximum number of thresholds before the switch trips:repair_time
- time taken for the switch to get fixed after it gets broken
telemetry
Telemetry
Being a big fan of observability, this library exposes information about it internals
using the community approved library (telemetry
). You can use the telemetry_poller
library to poll these metrics. Below are events that this library publishes.
Below are events published by trip_switch
:
[:trip_switch, :signal, :start]
- dispatched before a given signal is handled- Measurement:
%{system_time: system_time}
- Metadata:
%{id: atom(), tag: String.t()}
- Measurement:
[:trip_switch, :signal, :stop]
- dispatched after a given signal have been handled- Measurement:
%{duration: native_time}
- Metadata:
%{id: atom(), tag: String.t()}
- Measurement:
[:trip_switch, :repair, :start]
- dispatched when auto-repair is scheduled- Measurement:
%{system_time: system_time}
- Metadata:
%{id: atom(), tag: String.t()}
- Measurement:
[:trip_switch, :repair, :stop]
- dispatched after an auto-repair have been completed- Measurement:
%{duration: native_time}
- Metadata:
%{id: atom(), tag: String.t()}
- Measurement:
Link to this section Summary
Functions
Checks if the switch is broken.
Returns a specification to start this module under a supervisor.
Reset the given switch.
Send a signal to the underlying breaker.
Link to this section Functions
Checks if the switch is broken.
A switch is considered broken if the underlying breaker is half_open
or open
.
examples
Examples
iex> TripSwitch.broken?(:switch)
true
@spec child_spec(keyword()) :: Supervisor.child_spec()
Returns a specification to start this module under a supervisor.
See Supervisor
.
@spec reset(atom()) :: :ok
Reset the given switch.
Calling this function on a broken switch returns it to a working state.
examples
Examples
iex> TripSwitch.reset(:switch)
:ok
@spec send(atom(), TripSwitch.Breaker.signal()) :: {:ok, term()} | :broken
Send a signal to the underlying breaker.
The signal is a function that performs some actions then return a result that alters the state of the underlying breaker.
examples
Examples
iex> TripSwitch.send(:switch, fn -> {:ok, %{name: "a"}}) end)
{:ok, %{name: "a"}}
iex> TripSwitch.send(:switch, fn -> {:break, {:error, :not_found}} end)
{:error, :not_found}