66-supervise¶
The per-service process supervisor. 66-supervise keeps a single service running according to its declared policy: it runs the service's run script, restarts it when it dies (within a crash budget), runs its finish script on the way down, tracks readiness, and records the service's status. It is the native supervisor of 66 (historically inspired by s6-supervise) and is launched — one instance per service — by 66-scandir.
Interface¶
66-supervise servicename
66-supervise is not meant to be run directly. 66-scandir spawns it for every service it finds, with its current working directory set to the scandir and servicename as its only argument. The supervisor then changes into the service directory, reads the service's resolve database (./.resolve) and supervises it.
To act on a supervised service, use the friendly, resolve-aware commands 66 start, 66 stop and 66 signal; the low-level, resolve-independent control primitive is 66-svctl.
Behaviour¶
One 66-supervise process supervises exactly one service:
- It runs the service's
runscript and waits for it. When the process dies it is restarted, unless a down request is in effect (see Files). - For a service that declares a readiness notification descriptor, the supervisor waits for the service to announce it is ready before reporting it up and ready. It gives the service its
[Start] Timeoutto do so, counted from the start of its process, whatever brings it up. When the time runs out, the supervisor brings it down by the way down below, the service stays down and supervised, itsresultreadstimeout-startand thetimeout-startevent is sent; it is not started again until the next start. Without a readiness notification descriptor, a service is up as soon as its process starts, and nothing is timed. - When the service is brought down, the supervisor sends it the configured down signal, then runs the service's
finishscript before going back to a down state. The way down, thefinishscript included, waits for the[Stop] Timeoutof the service, never for its[Start] Timeout; once it has passed, the supervisor sendsSIGKILLand theresultreadstimeout-stop. A[Stop] Timeoutthe frontend does not write is the general stop delay chosen at the build of 66,10000milliseconds unless the-D default-stop-timeout=option ofmeson setupsays otherwise;0written means without end, and noSIGKILLis sent. A logger gets the general stop delay. - A service wanted up again while it is on its way down is not killed: it is brought back up.
- An order that does not change the state of the service, such as bringing up a service that runs, sends no event.
- At every transition it writes the service's status to
supervise/statusso that 66 status and the rest of66can report it.
Configuration¶
Unlike a classic supervisor that reads a set of per-service files, 66-supervise takes its configuration directly from the service's resolve database, compiled by 66 parse from the frontend file. The relevant frontend keys are:
Notify(in[Start]): the file descriptor on which the service announces its readiness.Timeout(in[Start]): the time a service withNotifyhas to become ready.Timeout(in[Stop]): the time the way down may take beforeSIGKILL, as written by the parse, the general stop delay when the frontend does not write it.MaxDeath/MaxDeathInterval(in[Start]): the crash budget (see Crash budget).DownSignal(in[Stop]): the signal sent to the service to bring it down.
The only configuration kept as a runtime file is down: its presence means keep the service down. 66 start and 66 stop create and remove it.
Files¶
66-supervise manages the following entries in the service's live directory:
supervise/status: a fixed-size binary status record (state, result, provenance, pid, timestamps and crash counter). It is read by 66 status.supervise/control: the control fifo on which the supervisor receives its commands.supervise/lock: guarantees that a single66-superviseprocess supervises a given service.down: the runtime down request described above.
Crash budget¶
If a service dies MaxDeath times (or more) within MaxDeathInterval milliseconds, 66-supervise stops restarting it and marks it as failed (crash limit reached). A successful 66 start resets the budget. Setting MaxDeath = 0 disables the budget entirely (infinite restart).
A service whose run script cannot be executed at all (for example a non-executable file) is reported as an exec failure with a progressive, bounded backoff; this is kept separate from the crash budget and never counts towards it.
Control¶
66-supervise listens on supervise/control for single-byte commands — bring up, bring down, restart, reload, send a signal, exit, and so on. You normally never write to this fifo yourself: 66 start, 66 stop, 66 signal and the 66-svctl primitive do it for you.