Malachi. Cluster. Membership
(malachi v0.22.7)
View Source
The pure state of SWIM-style cluster membership: who is :alive, :suspect, or :dead,
with per-member incarnation numbers. No processes, timers, or network: this is the
deterministic core that the failure detector and gossip transport
(Malachi.Cluster.MembershipServer) drive.
Each member owns its incarnation: only that member raises its own, to refute a false
suspicion. An update is {member, status, incarnation}, and merging updates is a join on the
lexicographic order {incarnation, rank} where rank is alive < suspect < dead. That single
rule yields the SWIM precedence:
- a higher incarnation always wins (a fresh
:aliveoverrides an old:suspect/:dead); - at equal incarnation,
:suspectoverrides:aliveand:deadoverrides both; - equal
{incarnation, rank}changes nothing (idempotent).
Because the merge is a commutative, associative, idempotent join, applying a batch of gossiped updates converges regardless of order, what makes infection-style dissemination correct.
The one exception is an update about self: a :suspect/:dead about us is refuted by
bumping our own incarnation above it and re-announcing :alive, so we never stay suspected while
running. apply_update/2 returns that refutation as an effect to disseminate.
Summary
Types
Opaque k/v an admin attaches to a broker (e.g. rack, dc); disseminated with the member.
What an applied update produced: a state change or a self-refutation to disseminate.
Functions
The sorted list of :alive members: the live broker set for placement and healing.
Applies one {member, status, incarnation} update under the SWIM precedence rules. Returns the
new view and an effect: {:applied, update} if it changed our state (disseminate it onward),
{:refute, update} if it was a false suspicion about us (announce the refutation), or :ignored.
The attributes of member (%{} if unknown or none set).
Confirms member :dead at its currently known incarnation.
The incarnation of member, or nil if unknown.
Applies a batch of updates (e.g. a received gossip), returning the new view and the list of
updates that changed state (applied changes plus any self-refutation) to disseminate onward.
Order-independent: the resulting view is the same for any permutation of updates.
Builds a membership view local to self, :alive at :incarnation (default 1).
:peers seeds other members :alive at incarnation 0, as placeholders until they announce
themselves. :attributes are self's own attributes (peers' attributes are learned via gossip).
Sets self's attributes, raising its own incarnation so the change wins the merge everywhere.
Returns the new view and {:applied, update} to disseminate (attributes are owned by their member).
The status of member, or nil if unknown.
Marks member :suspect at its currently known incarnation (a no-op if already overridden).
The full view as a list of {member, status, incarnation, attributes} updates, for gossiping.
Types
Opaque k/v an admin attaches to a broker (e.g. rack, dc); disseminated with the member.
What an applied update produced: a state change or a self-refutation to disseminate.
@type incarnation() :: non_neg_integer()
@type member() :: term()
@type member_state() :: %{ status: status(), incarnation: incarnation(), attributes: attributes() }
@type status() :: :alive | :suspect | :dead
@type t() :: %Malachi.Cluster.Membership{ members: %{required(member()) => member_state()}, self: member() }
@type update() :: {member(), status(), incarnation(), attributes()}
Functions
The sorted list of :alive members: the live broker set for placement and healing.
Applies one {member, status, incarnation} update under the SWIM precedence rules. Returns the
new view and an effect: {:applied, update} if it changed our state (disseminate it onward),
{:refute, update} if it was a false suspicion about us (announce the refutation), or :ignored.
@spec attributes(t(), member()) :: attributes()
The attributes of member (%{} if unknown or none set).
Confirms member :dead at its currently known incarnation.
@spec incarnation(t(), member()) :: incarnation() | nil
The incarnation of member, or nil if unknown.
Applies a batch of updates (e.g. a received gossip), returning the new view and the list of
updates that changed state (applied changes plus any self-refutation) to disseminate onward.
Order-independent: the resulting view is the same for any permutation of updates.
Builds a membership view local to self, :alive at :incarnation (default 1).
:peers seeds other members :alive at incarnation 0, as placeholders until they announce
themselves. :attributes are self's own attributes (peers' attributes are learned via gossip).
:incarnation is what a restart needs. The default outranks a placeholder, which is all a first
boot has to beat, but a node coming back has to outrank what its peers still remember of the member it
was, and that number is not derivable from anything this process holds. It is resumed from disk by
Malachi.Cluster.MemberIncarnation and handed in here.
@spec set_attributes(t(), attributes()) :: {t(), effect()}
Sets self's attributes, raising its own incarnation so the change wins the merge everywhere.
Returns the new view and {:applied, update} to disseminate (attributes are owned by their member).
The status of member, or nil if unknown.
Marks member :suspect at its currently known incarnation (a no-op if already overridden).
The full view as a list of {member, status, incarnation, attributes} updates, for gossiping.