Consistent vnode ownership for Elixir clusters.
Fief is instance-based: nothing runs under the :fief application itself.
Start instances in your own supervision tree, Ecto/Oban-style:
children = [
{Fief,
name: MyApp.Fief,
authority: {Fief.Authority.Local, []},
partitions: 64}
]The instance :name is the namespace — the identity of the coordination
domain, which must match across every node participating in this instance.
Multiple instances coexist in one BEAM and on one database.
See docs/design.md for guarantees and protocols, docs/implementation.md
for the code shape this module tree follows.
Summary
Functions
Optional instance-module sugar (implementation.md §9, deferred from M4 to
M6): defmodule MyApp.Fief do use Fief, partitions: 64, ... end generates a
module-named instance — child_spec/1 (runtime opts override use-time
opts; :name is always the module) plus call/3, cast/2, owner_of/1,
table/0, epoch/0, leader/0 wrapping the instance-first API. The core
stays plain opts; this is convenience only.
Call vnode of instance with msg and await the impl's reply:
{:ok, reply} or {:error, reason}. Runs in the caller (no router
process); opts takes :timeout (ms), covering the entire :moved-retry
loop. See Fief.Router.call/4.
Fire-and-forget send to vnode's owner. See Fief.Router.cast/3.
The epoch the cached table was read at. Hint-grade, an ETS read.
The current planner leader, {:ok, {node_id, term}}, answered from the
Authority through the instance's Leadership adapter. {:error, :disabled}
when the instance runs no leadership (leadership: false or no vnode impl).
The presumed owner of vnode — hint-grade. See Fief.Router.owner_of/2.
Start a Fief instance. Prefer {Fief, opts} in a supervision tree.
The cached vnode table — {:ok, %{vnode => {owner, prev_owner, row_epoch}}, epoch} — hint-grade, from this node's routing cache (an ETS read; the
Authority is the truth).
Functions
Optional instance-module sugar (implementation.md §9, deferred from M4 to
M6): defmodule MyApp.Fief do use Fief, partitions: 64, ... end generates a
module-named instance — child_spec/1 (runtime opts override use-time
opts; :name is always the module) plus call/3, cast/2, owner_of/1,
table/0, epoch/0, leader/0 wrapping the instance-first API. The core
stays plain opts; this is convenience only.
@spec call(atom(), non_neg_integer(), term(), keyword()) :: {:ok, term()} | {:error, Fief.Router.call_error()}
Call vnode of instance with msg and await the impl's reply:
{:ok, reply} or {:error, reason}. Runs in the caller (no router
process); opts takes :timeout (ms), covering the entire :moved-retry
loop. See Fief.Router.call/4.
@spec cast(atom(), non_neg_integer(), term()) :: :ok | {:error, Fief.Router.call_error()}
Fire-and-forget send to vnode's owner. See Fief.Router.cast/3.
@spec epoch(atom()) :: {:ok, non_neg_integer()} | {:error, :not_ready | :not_running}
The epoch the cached table was read at. Hint-grade, an ETS read.
@spec leader(atom()) :: {:ok, {term(), pos_integer()}} | {:error, :none | :unreachable | :disabled | :not_running}
The current planner leader, {:ok, {node_id, term}}, answered from the
Authority through the instance's Leadership adapter. {:error, :disabled}
when the instance runs no leadership (leadership: false or no vnode impl).
@spec owner_of(atom(), non_neg_integer()) :: {:ok, term()} | {:error, :no_owner | :unreachable | :not_running}
The presumed owner of vnode — hint-grade. See Fief.Router.owner_of/2.
@spec start_link(keyword()) :: Supervisor.on_start()
Start a Fief instance. Prefer {Fief, opts} in a supervision tree.
@spec table(atom()) :: {:ok, map(), non_neg_integer()} | {:error, :not_ready | :not_running}
The cached vnode table — {:ok, %{vnode => {owner, prev_owner, row_epoch}}, epoch} — hint-grade, from this node's routing cache (an ETS read; the
Authority is the truth).