sluice/consumer_supervisor

A demand-driven supervisor that starts one linked child for each event.

The supervisor owns both sides of the coordination: it receives events, starts and tracks linked children, applies restart policy, and returns demand only after a child finally terminates. Keeping those decisions in one process avoids races between a separate consumer and supervisor.

Child start functions must follow the OTP child contract: they return an actor.Started value whose process is linked to the caller. Child initialisation is synchronous, so it should finish quickly.

Types

Configuration for a consumer supervisor.

pub opaque type Builder(event, child_data)

A supervised child and its stable identifier.

pub type Child {
  Child(id: Int, status: ChildStatus)
}

Constructors

The visible state of a supervised child.

pub type ChildStatus {
  Running(pid: process.Pid)
  Restarting
  Terminating(pid: process.Pid)
}

Constructors

Counts of the children owned by a consumer supervisor.

pub type ChildrenCount {
  ChildrenCount(active: Int, restarting: Int, total: Int)
}

Constructors

  • ChildrenCount(active: Int, restarting: Int, total: Int)

A permanent name for a consumer supervisor.

pub opaque type Name(event, child_data)

When an event child is restarted.

pub type Restart {
  Transient
  Temporary
}

Constructors

  • Transient

    Restart a child only after an abnormal exit.

  • Temporary

    Never restart a child.

A reference to a running consumer supervisor.

pub opaque type Supervisor(event, child_data)
pub type TerminateError {
  ChildNotFound
  TerminateSupervisorNotAlive
}

Constructors

  • ChildNotFound
  • TerminateSupervisorNotAlive

Values

pub fn count_children(
  supervisor: Supervisor(event, child_data),
) -> Result(ChildrenCount, Nil)

Return child counts.

  • supervisor: The supervisor to query.
pub fn inlet(
  supervisor: Supervisor(event, child_data),
) -> sluice.Inlet(event)

Get the input face of a running supervisor.

  • supervisor: The supervisor, from start or supervisor_of.
pub fn inlet_of(
  name: Name(event, child_data),
) -> sluice.Inlet(event)

Get the input face of a named supervisor.

  • name: The name of the supervisor.
pub fn named(
  builder builder: Builder(event, child_data),
  name name: Name(event, child_data),
) -> Builder(event, child_data)

Give the supervisor a permanent name.

  • builder: The builder to change.
  • name: The name, from new_name.
pub fn new(
  start_child start_child: fn(event) -> Result(
    actor.Started(child_data),
    actor.StartError,
  ),
) -> Builder(event, child_data)

Define a consumer supervisor. Children are temporary by default.

  • start_child: The function that starts one linked child for one event. It must follow the OTP child contract.
pub fn new_name(prefix prefix: String) -> Name(event, child_data)

Make a permanent name. Create names during application start, not inside a dynamic loop.

  • prefix: The readable prefix of the name.
pub fn restart(
  builder builder: Builder(event, child_data),
  policy policy: Restart,
) -> Builder(event, child_data)

Set the child restart policy.

  • builder: The builder to change.
  • policy: The Restart policy for the children.
pub fn restart_tolerance(
  builder builder: Builder(event, child_data),
  max_restarts max_restarts: Int,
  within_seconds within_seconds: Int,
) -> Builder(event, child_data)

Set the maximum child restarts allowed during a period in seconds.

  • builder: The builder to change.
  • max_restarts: The maximum quantity of restarts in the period.
  • within_seconds: The length of the period in seconds.
pub fn shutdown_timeout(
  builder builder: Builder(event, child_data),
  milliseconds milliseconds: Int,
) -> Builder(event, child_data)

Set how long children have to stop before they are killed.

  • builder: The builder to change.
  • milliseconds: The maximum stop time in milliseconds.
pub fn start(
  builder: Builder(event, child_data),
) -> Result(
  actor.Started(Supervisor(event, child_data)),
  actor.StartError,
)

Start the supervisor as a linked OTP child.

  • builder: The configuration of the supervisor.
pub fn start_timeout(
  builder builder: Builder(event, child_data),
  milliseconds milliseconds: Int,
) -> Builder(event, child_data)

Set the maximum time allowed for supervisor initialisation.

  • builder: The builder to change.
  • milliseconds: The maximum start time in milliseconds.
pub fn subscribe(
  builder builder: Builder(event, child_data),
  options options: sluice.SubscriptionOptions(event),
) -> Builder(event, child_data)

Declare a subscription that is established when the supervisor starts. Consumer supervisors own their demand loop, so the subscription must use the default Automatic demand mode.

  • builder: The builder to change.
  • options: The subscription options, from sluice.subscription.
pub fn supervisor_of(
  name: Name(event, child_data),
) -> Supervisor(event, child_data)

Make a reference to the process using a name.

  • name: The name of the supervisor.
pub fn terminate_child(
  supervisor supervisor: Supervisor(event, child_data),
  pid pid: process.Pid,
) -> Result(Nil, TerminateError)

Ask a child to stop. A successfully terminated event child frees its slot, and the demand returns to its producer.

  • supervisor: The supervisor that owns the child.
  • pid: The pid of the child.
pub fn whereis(
  name: Name(event, child_data),
) -> Result(process.Pid, Nil)

Find the process currently using a name.

  • name: The name of the supervisor.
pub fn which_children(
  supervisor: Supervisor(event, child_data),
) -> Result(List(Child), Nil)

Return the supervisor’s current children.

  • supervisor: The supervisor to query.
Search Document