PhiAccrual (phi_accrual v1.1.0)
View Sourceφ-accrual failure detector — public API.
The detector emits a continuous suspicion value φ per monitored node.
φ grows monotonically with time since the last heartbeat and is
calibrated against observed inter-arrival statistics (EWMA mean and
variance). See PhiAccrual.Core for the math and README.md for
the positioning (observability-grade, not decision-grade in v1).
Typical usage (bring-your-own-signal)
# Track a node with default estimator settings.
PhiAccrual.track(:node_a@host)
# Call observe/2 from wherever you already receive cross-node
# traffic — GenServer replies, :pg broadcasts, your own pings.
PhiAccrual.observe(:node_a@host)
# Query φ at any time.
PhiAccrual.phi(:node_a@host)
#=> {:ok, 1.82, :steady}observe/1 auto-tracks unknown nodes with default settings — call
track/2 first if you want custom per-node estimator options.
The monitored key is an Erlang node() when fed by the bundled
DistributionPing source, but the detector treats the key opaquely
and accepts any term — see detector_key/0 for the contract used
by non-distribution transport companion packages.
Overload behaviour
observe/2 is bounded: if the target estimator's mailbox exceeds
:shed_threshold (default 10_000) the sample is dropped and a
[:phi_accrual, :overload, :shed] telemetry event is emitted. For
failure detection you don't need every heartbeat, you need enough
heartbeats — if you're shedding, your heartbeat rate is too high for
your EWMA α settings. Tune α before raising the threshold.
Summary
Functions
Return the current PhiAccrual.Core estimator state for node, or
{:error, :not_tracked} if the node is not tracked.
Record a heartbeat arrival for node at the current monotonic time.
Auto-tracks the node with default options if not already tracked.
Record a heartbeat arrival for node at monotonic-ms ts.
Current φ for node. See PhiAccrual.Core.phi_result/0.
Start tracking node with optional estimator configuration.
List all currently-tracked nodes.
Stop tracking node. No-op if the node is not tracked.
Types
Identity of a monitored entity.
Historically this was always an Erlang node(), and for the bundled
DistributionPing source it still is. Transport companion packages
(phi_accrual_udp, phi_accrual_amqp, ...) monitor entities that are
not BEAM nodes — a UDP peer, an AMQP routing key — so the key may be
any term: a string, a tuple, an atom.
The detector treats the key opaquely: it is a Registry key and a
telemetry metadata value, nothing more. Two rules apply:
@type phi_result() :: PhiAccrual.Core.phi_result()
Functions
@spec inspect_state(detector_key()) :: PhiAccrual.Core.t() | {:error, :not_tracked}
Return the current PhiAccrual.Core estimator state for node, or
{:error, :not_tracked} if the node is not tracked.
Intended for IEx introspection and debugging — inspect mean,
variance, samples_seen, last_interval_ms, and last_arrival_ts
to see what the estimator currently believes about a node. Not for
hot-path use.
@spec observe(detector_key()) :: :ok
Record a heartbeat arrival for node at the current monotonic time.
Auto-tracks the node with default options if not already tracked.
@spec observe(detector_key(), integer()) :: :ok
Record a heartbeat arrival for node at monotonic-ms ts.
ts must come from the same local monotonic clock as Clock.now/0.
Cross-node timestamps are meaningless for the detector and must never
enter interval calculations.
@spec phi(detector_key()) :: phi_result() | {:error, :not_tracked}
Current φ for node. See PhiAccrual.Core.phi_result/0.
@spec track( detector_key(), keyword() ) :: {:ok, pid()} | {:error, term()}
Start tracking node with optional estimator configuration.
core_opts are forwarded to PhiAccrual.Core.new/1.
@spec tracked_nodes() :: [detector_key()]
List all currently-tracked nodes.
@spec untrack(detector_key()) :: :ok
Stop tracking node. No-op if the node is not tracked.