SwimEx. Membership
(SwimEx v0.1.0)
View Source
Pure functional membership state machine.
Tracks cluster members and their states. All functions return a new state; no side effects.
Incarnation rules (SWIM+Susp)
alive(node, inc): accepted if inc > current_inc, OR if node is unknown (new join). Dead nodes revived only if inc > dead_inc (restart with time-based incarnation ensures this).suspect(node, inc): accepted if inc >= current_inc and node is alive or suspect.dead(node, inc): accepted if inc >= current_inc and node is not already dead.
Summary
Functions
Adds a new node to the membership state with the given incarnation.
Applies a gossip event to the membership state.
Garbage collects dead members that have been dead for longer than expiry_ms.
Returns the membership entry for a node, or nil if not found.
Lists members in the cluster.
Returns the count of non-dead members (alive or suspect).
Returns a new, empty membership state.
Marks a node as alive with the given incarnation.
Types
@type member() :: %{ status: status(), incarnation: non_neg_integer(), dead_at: integer() | nil }
@type node_id() :: {String.t(), :inet.port_number(), String.t()}
@type status() :: :alive | :suspect | :dead
Functions
@spec add(t(), node_id(), non_neg_integer()) :: t()
Adds a new node to the membership state with the given incarnation.
Returns the updated membership state.
@spec apply_event(t(), SwimEx.Codec.event()) :: t()
Applies a gossip event to the membership state.
Follows SWIM+Suspension rules for state transitions and incarnation numbers. Returns the updated membership state.
@spec gc(t(), non_neg_integer()) :: t()
Garbage collects dead members that have been dead for longer than expiry_ms.
Returns the updated membership state.
Returns the membership entry for a node, or nil if not found.
@spec list( t(), keyword() ) :: [ {String.t(), :inet.port_number(), String.t(), status(), non_neg_integer()} ]
Lists members in the cluster.
Options
:include_dead: Boolean. If true, includes nodes marked as dead. Defaults tofalse.
Returns
- A list of member tuples:
{host, port, cookie, status, incarnation}.
@spec member_count(t()) :: non_neg_integer()
Returns the count of non-dead members (alive or suspect).
@spec new() :: t()
Returns a new, empty membership state.
@spec set_alive(t(), node_id(), non_neg_integer()) :: t()
Marks a node as alive with the given incarnation.
Returns the updated membership state.