Trebejo.Breaker (Trebejo v2.0.0)

Copy Markdown View Source

Circuit-breaker integration for Trebejo commands.

Wraps any Trebejo command execution in Arrea.CircuitBreaker.call/3 so that a flaky dependency (e.g. a remote SSH host, a slow docker daemon) trips the breaker after a few failures and the rest of your pipeline fails fast instead of piling up requests.

Usage

Wrap an arbitrary command:

Trebejo.Breaker.with_breaker(:ssh_prod, fn ->
  Trebejo.Runner.run("ssh", ["prod-1", "systemctl restart nginx"])
end)

Or pass breaker: name to a wrapper:

Trebejo.Docker.ps(breaker: :docker_local)

Telemetry

Emits standard [:arrea, :circuit_breaker, ...] events. See Arrea.Telemetry.Events.circuit_breaker_metadata/0.

See also

Summary

Functions

Notify the breaker of an explicit failure.

Read the breaker's current state.

Notify the breaker of an explicit success.

Execute fun under the breaker identified by name.

Functions

failure(name)

@spec failure(atom()) :: :ok

Notify the breaker of an explicit failure.

Use this when you've already executed the side-effect outside of with_breaker/3 and want the breaker to record a failure (which may trip it).

state(name)

@spec state(atom()) :: :closed | :open | :half_open | nil

Read the breaker's current state.

Returns one of :closed | :open | :half_open, or nil if no breaker is registered under name.

Note: a brand-new :closed state for an unstarted breaker is indistinguishable from a healthy running breaker. There is no way to tell "never started" from "started but no failures yet" from the public API of Arrea.CircuitBreaker. If you need to know whether the breaker exists, call Arrea.CircuitBreaker.start_link/1 with the same name and trap {:error, {:already_started, _}}.

success(name)

@spec success(atom()) :: :ok

Notify the breaker of an explicit success.

Use this when you've already executed the side-effect outside of with_breaker/3 and want the breaker to record a success.

with_breaker(name, fun, opts \\ [])

@spec with_breaker(atom(), (-> term()), keyword()) :: term()

Execute fun under the breaker identified by name.

The breaker must have been started elsewhere (typically in your application's supervision tree). Returns whatever the wrapped call returns, or {:error, %Trebejo.Error{kind: :circuit_open}} if the breaker is open.

Options

  • :threshold — default 3 (passed to the breaker if it has to be started lazily).
  • :timeout — default 30_000 ms.
  • :required_successes — default 1.

See Arrea.CircuitBreaker.start_link/1 for the full set of options.