breaker v0.1.0 Breaker.Agent
Maintains the state for a particular circuit breaker.
This Agent holds the constantly changing state properties of the circuit and the information required to calculate those.
Summary
Functions
Recalculates if the given Breaker.Agent state should be open or closed
Count a response in the current bucket of the window
Count a hit (sucessful request) in the current window and sums of the passed Map
Count a miss (error) in the current window and the sum of the passed Map
Check if the circuit is open (broken)
Calculate if the circuit should be open or closed
Reset an open breaker
Roll the window, creating a new bucket and possible pushing out an old one, updating the sum values as necessary
Roll the calculation window for the given Breaker.Agent.t
Start a new circuit breaker state holder
Manually trip the circuit, setting it to an “open” status
Types
Functions
Recalculates if the given Breaker.Agent state should be open or closed.
Checks the total number of requests and errors in the rolling window and
trips the circuit if it’s higher than error_threshold
.
count(pid, %HTTPotion.Response{body: term, headers: term, status_code: term} | %HTTPotion.ErrorResponse{message: term}) :: :ok
Count a response in the current bucket of the window.
Parameters:
circuit
: The Agent containing the circuit’s state.response
: The received%HTTPotion.Response{}
Examples:
iex> window = [%{total: 0, errors: 0}]
iex> {:ok, circuit} = Breaker.Agent.start_link(%{window: window})
iex> Breaker.Agent.count(circuit, %HTTPotion.Response{status_code: 200})
:ok
iex> window = [%{total: 1, errors: 0}]
iex> {:ok, circuit} = Breaker.Agent.start_link(%{window: window})
iex> Breaker.Agent.count(circuit, %HTTPotion.Response{status_code: 500})
:ok
iex> window = [%{total: 0, errors: 0}, %{total: 2, errors: 1}]
iex> {:ok, circuit} = Breaker.Agent.start_link(%{window: window})
iex> Breaker.Agent.count(circuit, %HTTPotion.Response{status_code: 200})
:ok
Count a hit (sucessful request) in the current window and sums of the passed Map.
Examples:
iex> circuit = %{window: [%{total: 0, errors: 0}], sum: %{total: 0, errors: 0}}
iex> Breaker.Agent.count_hit(circuit)
%{window: [%{total: 1, errors: 0}], sum: %{total: 1, errors: 0}}
Count a miss (error) in the current window and the sum of the passed Map.
Examples:
iex> circuit = %{window: [%{total: 0, errors: 0}], sum: %{total: 0, errors: 0}}
iex> Breaker.Agent.count_miss(circuit)
%{window: [%{total: 1, errors: 1}], sum: %{total: 1, errors: 1}}
Check if the circuit is open (broken).
Parameters:
circuit
: The Agent containing the circuit’s state.
Examples:
iex> {:ok, circuit} = Breaker.Agent.start_link(%{open: false})
iex> Breaker.Agent.open?(circuit)
false
iex> {:ok, circuit} = Breaker.Agent.start_link(%{open: true})
iex> Breaker.Agent.open?(circuit)
true
Calculate if the circuit should be open or closed.
Parameters:
circuit
: The Agent containing the circuit’s state.
Examples:
iex> sum = %{total: 10, errors: 10}
iex> options = %{error_threshold: 0.05, sum: sum, open: false}
iex> {:ok, circuit} = Breaker.Agent.start_link(options)
iex> Breaker.Agent.open?(circuit)
false
iex> Breaker.Agent.recalculate(circuit)
iex> Breaker.Agent.open?(circuit)
true
Reset an open breaker.
Parameters:
circuit
: The Agent containing the circuit’s state.
Examples:
iex> {:ok, circuit} = Breaker.Agent.start_link(%{open: true})
iex> Breaker.Agent.reset(circuit)
iex> Breaker.Agent.open?(circuit)
false
iex> {:ok, circuit} = Breaker.Agent.start_link(%{open: false})
iex> Breaker.Agent.reset(circuit)
iex> Breaker.Agent.open?(circuit)
false
Roll the window, creating a new bucket and possible pushing out an old one, updating the sum values as necessary.
Parameters:
circuit
: The Agent containing the circuit’s state.
Examples:
iex> options = %{window: [%{total: 1, errors: 0}]}
iex> {:ok, circuit} = Breaker.Agent.start_link(options)
iex> Breaker.Agent.roll(circuit)
:ok
Roll the calculation window for the given Breaker.Agent.t.
This creates a new current bucket, pushing the existing ones down the line,
potentially removes the oldest one (if window_length
has been reached), and
recalculates the status of the breaker.
Start a new circuit breaker state holder.
The internal state looks like the following:
%{
open: false,
error_threshold: 0.05,
window_length: 10,
bucket_length: 1000,
sum: %{
total: 0,
errors: 0
},
window: [
%{
total: 0,
errors: 0
},
...
]
}
Parameters:
options
: An options map. It should contain the following keys:open
: A boolean indicating if the circuit is open or not.
error_threshold
: The percent of requests allowed to fail, as a float.window_length
: The number of buckets in the health calculation window.bucket_length
: The number of milliseconds for each bucket.
Examples:
iex> {:ok, circuit} = Breaker.Agent.start_link(%{misses: 0})
iex> is_pid(circuit)
true
Manually trip the circuit, setting it to an “open” status.
Paramaters:
circuit
: The Agent containing the circuit’s state.
Examples:
iex> {:ok, circuit} = Breaker.Agent.start_link(%{open: false})
iex> Breaker.Agent.trip(circuit)
iex> Breaker.Agent.open?(circuit)
true
iex> {:ok, circuit} = Breaker.Agent.start_link(%{open: true})
iex> Breaker.Agent.trip(circuit)
iex> Breaker.Agent.open?(circuit)
true