Hive.Supervisor
hive · API reference
OTP-style supervision trees.
Supervision: OTP restart strategies + Cats Effect's await flag.
A supervisor owns a sub-switch; children run under it, so switch cancellation is structured shutdown for free. The restart loop consults each child's Outcome.t. Backoff is exponential and capped; it resets after a child has stayed up longer than the cap.
v1 notes: no restart-intensity limit (a permanently crashing child keeps restarting at the capped backoff rate) and no jitter — both deliberate omissions, revisit with measurements.
type strategy =
| One_for_one (* Restart only the failed child. *)
| One_for_all (* Restart all children if one fails. *)
| Rest_for_one (* Restart the failed child and those started after it. *)type restart =
| Permanent (* Always restarted. *)
| Transient (* Restarted only after a Failed outcome. *)
| Temporary (* Never restarted. *)type backoff = {
initial : float; (* First restart delay, seconds. *)
max_delay : float; (* Cap; also the uptime after which it resets. *)
multiplier : float; (* Exponential factor. *)
}val default_backoff : backoff{ initial = 0.05; max_delay = 5.0; multiplier = 2.0 }
type child = {
join : unit Outcome.t Eio.Promise.t;
shutdown : unit -> unit;
}What a supervisor needs from a running child: a way to observe its end and a way to ask it to stop. Worker, Server and Task all provide both.
type child_specDeclarative description of a child to start and possibly restart.
val child_spec :
?restart:restart ->
?backoff:backoff ->
id:string ->
(Eio.Switch.t -> child) ->
child_specchild_spec ~id start describes a child. start receives the supervisor's sub-switch and is re-run on every restart. restart defaults to Permanent.
ocaml]
let spec =
Hive.Supervisor.child_spec ~id:"logger" (fun sw ->
Hive.Supervisor.child_of_fn sw (fun () -> run_logger ()))val child_of_fn : Eio.Switch.t -> (unit -> unit) -> childAdapt a plain thunk (run as a Task) into a supervisable child.
type tA running supervisor.
val start :
sw:Eio.Switch.t ->
clock:_ Eio.Time.clock ->
?strategy:strategy ->
?await:bool ->
child_spec list ->
tStarts the children in order, then supervises. strategy defaults to One_for_one. await (default false) controls stop: true waits for running children to finish on their own; false asks each to shut down (Cats Effect default). Raises Invalid_argument on duplicate child ids.
ocaml]
let supervisor =
Hive.Supervisor.start ~sw ~clock
~strategy:Hive.Supervisor.One_for_one
[spec]val stop : t -> unitAsk the supervisor to stop (see await above). Idempotent.
val join : t -> unit Outcome.t Eio.Promise.tResolved when the supervisor itself finishes.