Skip to content

Membership ​

After discovery has joined a node to the cluster, membership takes over. Every node keeps a live view of the cluster: who is in it, when each member joined, and whether each is ready or draining. Nodes gossip that view to each other continuously, and a lightweight failure detector notices when a node stops responding. Every topology change after boot, a join, a leave, a failure, or a metadata change, is reported by membership, not by discovery.

JoiningAliveSuspectDeadview convergesprobes missedanswers againconfirmedstop()Leavingdeparts

The runtime uses a gossip-based membership protocol with a probe-and-suspect failure detector tuned for a local network: a member that misses its probes is suspected, other members corroborate, and if it stays silent it is confirmed dead; a member that answers again before confirmation is revived. A node that stops gracefully broadcasts its departure, so survivors learn of it at once rather than waiting for detection.

The coordinator ​

Exactly one member is the coordinator: the oldest live member, the one deterministic choice every node's view agrees on. It is not elected and holds no lease; it is simply whoever has been in the cluster longest, and it changes only when that member departs, at which point the next-oldest takes over.

The coordinator is the single driver of cluster-wide work that must happen once:

  • It recomputes registry partition ownership on every membership change (rebalancing).
  • It drives relocation: when a node departs, only the coordinator recreates that node's actors on the survivors. Every other survivor just refreshes its routing caches.

Because the choice is deterministic, a coordinator that dies is replaced without an election, and a successor recomputes the same work and resumes it idempotently.

Split-brain and quorum ​

A network partition can split a cluster into halves that can no longer gossip. If both halves keep serving, each could believe it holds a name and mint a second instance, breaking cluster-wide uniqueness and singletons. The split-brain resolver prevents that: set minimumMemberQuorum to the smallest number of members a functioning half must see, and a half that falls below it stops rather than serving on.

ts
new ActorSystem("orders", {
  remote: { host: "0.0.0.0", advertisedHost: host, port: 4000 },
  cluster: { discovery, minimumMemberQuorum: 2 },
});

WARNING

minimumMemberQuorum defaults to 1, which disables the resolver. Name uniqueness and at-most-one singletons depend on the resolver being on, so a real clustered deployment sets a quorum (typically a majority of the expected size). Leaving it at 1 is fine for a single node or a test, not for production.

Ready and draining ​

A member carries a ready flag (it has finished joining and can take placements) and a draining flag (it is leaving and should take no new ones). Placement strategies and relocation only ever choose live, ready, non-draining members as targets, so a node that is still joining or already leaving never receives a fresh actor.

Observing membership ​

Every membership change reaches your code as an event on the system stream. Subscribe to watch the cluster form and change:

ts
system.subscribe((event: unknown): void => {
  if (event instanceof NodeJoined) console.log("joined", event.address);
  if (event instanceof NodeLeft) console.log("left", event.address);
  if (event instanceof CoordinatorChanged) console.log("coordinator", event.coordinator);
});

See cluster events for the full family, including the rebalance and relocation events.

Released under the MIT License.