distribute/cluster_monitor

Cluster-event monitor.

Wraps Erlang’s net_kernel:monitor_nodes/1 in a typed actor. Subscribers register a Subject(ClusterEvent) and receive NodeUp(name) / NodeDown(name) events for the lifetime of the monitor. Subscribers are pruned proactively on owner death via process.monitor, so the subscriber list is bounded under churn regardless of cluster activity.

Types

pub type ClusterEvent {
  NodeUp(node: String)
  NodeDown(node: String)
}

Constructors

  • NodeUp(node: String)
  • NodeDown(node: String)

User-facing protocol for the cluster monitor.

opaque so external code cannot construct internal variants (e.g. SubscriberDown, ClassifiedNodeEvent, UnknownMessage) and inject them through process.send to corrupt the monitor’s state. The public surface is subscribe/2 and unsubscribe/2, which build Subscribe/Unsubscribe themselves. Callers never need to name the constructors directly.

pub opaque type Message

Values

pub fn start_observed(
  on_unknown_msg: fn(dynamic.Dynamic) -> Nil,
) -> Result(process.Subject(Message), actor.StartError)

Like start, but fires on_unknown_msg(dyn) whenever the monitor receives a mailbox term it cannot classify as a Subject message or a recognised nodeup/nodedown event. Useful as a diagnostic hook Silent drops in cluster discovery are a debugging nightmare.

pub fn subscribe(
  monitor: process.Subject(Message),
  listener: process.Subject(ClusterEvent),
) -> Nil

Subscribe listener to receive NodeUp/NodeDown events from monitor. Idempotent: subscribing the same listener twice produces a single subscription (the handler dedups internally).

See also: unsubscribe/2, start/0, start_observed/1.

pub fn unsubscribe(
  monitor: process.Subject(Message),
  listener: process.Subject(ClusterEvent),
) -> Nil

Unsubscribe listener from monitor. The corresponding process.monitor is demonitored so we no longer hear about the owner’s death.

Search Document