mule/runtime/sonar

Notifier-health monitor — a port of Oban.Sonar. A self-rescheduling actor that broadcasts a heartbeat on the Gossip channel and records which nodes it hears back from, classifying the notifier’s reach as:

Detection is a notifier round-trip, not an mule_peers count: only a ping that comes back proves the notifier is actually delivering, and a count cannot tell Isolated from Solitary. The Stager reads the resulting status to choose how its wake-ups travel: cluster-wide through the notifier (Global) or straight to each node’s own producers (Local, used when the notifier cannot fan out cross-node).

Like the peer, the status is published to the cell (peer/cell) and read with the total status/1 function — the Stager never calls this process.

Types

pub type Message {
  PingTick
  Heard(notifier.Notification)
}

Constructors

pub type State {
  State(
    instance_name: String,
    node: String,
    notifier: notifier.Notifier,
    nodes: dict.Dict(String, Int),
    status: Status,
    interval: Int,
    notification_subject: process.Subject(notifier.Notification),
    self_subject: process.Subject(Message),
  )
}

Constructors

pub type Status {
  Unknown
  Isolated
  Solitary
  Clustered
}

Constructors

  • Unknown
  • Isolated
  • Solitary
  • Clustered

Values

pub fn adjust_interval(
  status status: Status,
  node_count node_count: Int,
  changed changed: Bool,
  interval interval: Int,
) -> Int

On a change (status or node set), drop back to the fastest cadence to converge quickly; otherwise DOUBLE the current interval toward a target — scaled with the cluster size when clustered (peer pings prove liveness), the full backoff when solitary — rather than jumping straight to it. Mirrors sonar.ex adjust_interval, including its max(nodes, 1) clamp. Public for tests: the ramp is otherwise observable only through timing.

pub fn child(
  instance_name instance_name: String,
  node node: String,
  notifier notifier: notifier.Notifier,
) -> supervision.ChildSpecification(Nil)

Supervise the Sonar actor as a single worker. Takes only what it needs (not the whole Config), avoiding the startup cycle.

pub fn put_status(
  instance_name instance_name: String,
  status status: Status,
) -> Nil

Publish a classification for instance_name — written on every tick and heartbeat; also the hook tests use to force a Stager mode.

pub fn status(instance_name instance_name: String) -> Status

The current notifier-health status for instance_name, or Unknown when no Sonar is running / it has not completed a round-trip yet. A total, non-blocking cell read — the Stager’s hot path.

Search Document