mule/runtime/peer_database

The Postgres lease-election peer — a faithful port of Oban.Peers.Database. A self-rescheduling actor that competes for the single mule_peers row for its instance name: it acquires the lease when free, renews it while held, and lets it expire to hand leadership off. On every tick it writes its current leadership into the cell (peer), which the cron/pruner/stager gates read without ever calling this process.

Key correctness properties (see the C-P spec):

Types

pub type Message {
  Elect
  LeaderHeard(notifier.Notification)
  Shutdown
}

Constructors

pub type State {
  State(
    name: String,
    node: String,
    engine: engine.Engine,
    notifier: notifier.Notifier,
    interval: duration.Duration,
    is_leader: Bool,
    consecutive_errors: Int,
    self_subject: process.Subject(Message),
  )
}

Constructors

Values

pub fn child(
  name name: String,
  engine engine: engine.Engine,
  notifier notifier: notifier.Notifier,
  node node: String,
  interval interval: duration.Duration,
) -> supervision.ChildSpecification(Nil)

Supervise the peer actor as a single worker. Takes only what the actor needs (name, engine, notifier, node, interval) rather than the whole Config, so it does not depend on the peer.Peer that Config carries — breaking the startup cycle.

pub fn reader(
  name name: String,
  engine engine: engine.Engine,
) -> peer.Peer

Build the Peer read surface for the Postgres backend: leadership is the pure cell read (the gate hot path), and get_leader queries the database (engine.read_leader), exactly as Oban.Peer.get_leader does.

pub fn start(
  name: String,
  engine: engine.Engine,
  notifier: notifier.Notifier,
  node: String,
  interval: duration.Duration,
) -> Result(
  actor.Started(process.Subject(Message)),
  actor.StartError,
)

Start the peer actor directly (the child spec wraps this). Public so a test can hold the actor’s Subject and address its process.

Search Document