View Source ProcessHub.Service.Cluster (ProcessHub v0.8.0)

ProcessHub instances with the same hub_id will automatically form a cluster. The cluster service provides API functions for managing the cluster.

Summary

Functions

Adds a new node to the hub cluster and returns new list of nodes.

Sends this node's boot token to members so they can reap any bindings left over from a previous incarnation. Sent to every peer on every boot, for every backend, and to each node this node greets on a join, so a peer that joined later knows the token before a restarted coordinator announces it again.

Generates a boot token that is stable for the lifetime of the node and differs across restarts. Broadcast to peers so they can tell a restart from a flap.

Sends msg to the locally-registered process module on every cluster node, including the local node.

Handles a peer's boot announcement: purges the peer's registry bindings the first time a given token is seen (a genuine restart), and does nothing when the token is unchanged (a network flap or a duplicate announcement).

Handles the node down event by dispatching hooks, removing nodes from cluster state, and triggering the node down update task.

Handles the node up event by dispatching hooks, adding nodes to cluster state, checking partition tolerance for quorum recovery, and triggering the node up update task.

Returns the remote nodes whose hub coordinator is in the hub's pg group, that is, the nodes running the hub now. An empty list while peers are connected means the group never synced.

Asks the partition tolerance strategy about each departed node and locks the hub when it says so. kind is :leave for a node that drained or stopped its hub while connected, and :down for a node that disappeared. Call it after the nodes have left the membership.

Returns a boolean indicating whether the node exists in the cluster.

Returns a list of nodes in the cluster.

Promotes the current node to a cluster node.

Withdraws the observations of every node that is not part of the hub's current cluster. Returns the list of purged dead nodes.

Withdraws every process-registry observation that references node. Returns the affected child_ids.

Removes a node from the cluster and returns new list of nodes.

Functions

Link to this function

add_hub_node(misc_storage, node)

View Source
@spec add_hub_node(:ets.tid(), node()) :: [node()]

Adds a new node to the hub cluster and returns new list of nodes.

Link to this function

announce_boot(hub, token, members \\ :external)

View Source
@spec announce_boot(ProcessHub.Hub.t(), integer(), :external | [node()]) :: :ok

Sends this node's boot token to members so they can reap any bindings left over from a previous incarnation. Sent to every peer on every boot, for every backend, and to each node this node greets on a join, so a peer that joined later knows the token before a restarted coordinator announces it again.

@spec boot_token() :: integer()

Generates a boot token that is stable for the lifetime of the node and differs across restarts. Broadcast to peers so they can tell a restart from a flap.

@spec broadcast(module(), term()) :: :ok

Sends msg to the locally-registered process module on every cluster node, including the local node.

Link to this function

handle_boot_announcement(hub, peer, token, purge? \\ true)

View Source
@spec handle_boot_announcement(ProcessHub.Hub.t(), node(), integer(), boolean()) ::
  :restarted | :unchanged

Handles a peer's boot announcement: purges the peer's registry bindings the first time a given token is seen (a genuine restart), and does nothing when the token is unchanged (a network flap or a duplicate announcement).

This closes the fast-restart stale-binding gap for every backend — the stale {peer, dead_pid} rows live on the local (peer) node, independent of the restarted node's :registry_backend. Purging only withdraws observations: a child left with no observation is restarted by the :auto_recovery reconcile round, and nothing restarts it without one. Any binding wiped by a late announcement is re-asserted by the returning node's next sync.

With purge? false the token is recorded and the bindings are left for the caller, which re-places the node's children through the node-down path. Answers :restarted for a new token and :unchanged otherwise.

Handles the node down event by dispatching hooks, removing nodes from cluster state, and triggering the node down update task.

Handles the node up event by dispatching hooks, adding nodes to cluster state, checking partition tolerance for quorum recovery, and triggering the node up update task.

@spec hub_peers(ProcessHub.Hub.t()) :: [node()]

Returns the remote nodes whose hub coordinator is in the hub's pg group, that is, the nodes running the hub now. An empty list while peers are connected means the group never synced.

Link to this function

lock_on_departure(hub, nodes, kind)

View Source
@spec lock_on_departure(ProcessHub.Hub.t(), [node()], :down | :leave) :: :ok

Asks the partition tolerance strategy about each departed node and locks the hub when it says so. kind is :leave for a node that drained or stopped its hub while connected, and :down for a node that disappeared. Call it after the nodes have left the membership.

@spec new_node?([node()], node()) :: boolean()

Returns a boolean indicating whether the node exists in the cluster.

Link to this function

nodes(misc_storage, opts \\ [])

View Source
@spec nodes(:ets.tid(), [:include_local | :connected] | nil) :: [node()]

Returns a list of nodes in the cluster.

:include_local keeps the local node in the list; :connected drops members the local node is no longer connected to.

Link to this function

promote_to_node(hub, node_name)

View Source
@spec promote_to_node(ProcessHub.Hub.t(), node()) :: :ok | {:error, :not_alive}

Promotes the current node to a cluster node.

Link to this function

purge_dead_nodes(hub_id)

View Source
@spec purge_dead_nodes(ProcessHub.hub_id()) :: [node()]

Withdraws the observations of every node that is not part of the hub's current cluster. Returns the list of purged dead nodes.

Observation-only, like purge_node/2; it does not redistribute. Intended for out-of-band reconcile and cold-boot replay sanitisation.

Link to this function

purge_node(hub_id, node)

View Source
@spec purge_node(ProcessHub.hub_id(), node()) :: [ProcessHub.child_id()]

Withdraws every process-registry observation that references node. Returns the affected child_ids.

This is a dead-node maintenance primitive for the cases the automatic :nodedown purge does not cover — for example {dead_node, pid} rows replayed from a durable registry at cold boot, where no :nodedown event ever fires. A child left with no observation keeps its row and becomes an orphan-reconcile candidate; re-placement is the caller's job.

Link to this function

rem_hub_node(misc_storage, node)

View Source
@spec rem_hub_node(:ets.tid(), node()) :: [node()]

Removes a node from the cluster and returns new list of nodes.