Process supervision and management
Assertions requiring a service with name matching
DaemonService
cause the server to start a subprocess-based service:
DaemonService = <daemon @id any> .
Each daemon
service can have zero or more subprocesses associated with it. Subprocesses can
be long-lived services or short-lived, system-state-changing programs or scripts.
Adding process specifications to a service
Each subprocess associated with a DaemonService
is defined with a DaemonProcess
assertion:
DaemonProcess = <daemon @id any @config DaemonProcessSpec>.
DaemonProcessSpec =
/ @simple CommandLine
/ @oneShot <one-shot @setup CommandLine>
/ @full FullDaemonProcess .
The simplest kind of subprocess specification is a CommandLine
, either a string (sent to sh -c
) or an array of program name (looked up in the $PATH
) and arguments:
CommandLine = @shell string / @full FullCommandLine .
FullCommandLine = [@program string, @args string ...] .
The simple
and oneShot
variants of DaemonProcessSpec
expand into FullDaemonProcess
values as follows:
- a
simple
command-line c becomes{ argv:
c}
; and - a record
<one-shot
c>
becomes{ argv:
c, readyOnStart: false, restart: on-error }
.
Subprocess specification
The FullDaemonProcess
type matches a Preserves dictionary having, at minimum, an argv
key,
and optionally including many other parameters controlling various aspects of the subprocess to
be created.1
FullDaemonProcess =
& @process FullProcess
& @readyOnStart ReadyOnStart
& @restart RestartField
& @protocol ProtocolField .
FullProcess =
& { argv: CommandLine }
& @env ProcessEnv
& @dir ProcessDir
& @clearEnv ClearEnv .
The CommandLine
associated with argv
specifies the program name to invoke and its
command-line arguments. The other options are described in the remainder of this section.
Ready-signalling
If the key readyOnStart
is present in a FullDaemonProcess
dictionary, then if its
associated value is #t
(the default), the service will be considered
ready
immediately after it has been spawned; if its value is
#f
, some other arrangement is expected to be made to announce a ready
ServiceState
against the service's name.
ReadyOnStart =
/ @present { readyOnStart: bool }
/ @invalid { readyOnStart: any }
/ @absent {} .
Whether and when to restart
The default restart policy is always
. It can be overridden by providing the key restart
a
FullDaemonProcess
dictionary, mapping to a valid RestartPolicy
value.
RestartField =
/ @present { restart: RestartPolicy }
/ @invalid { restart: any }
/ @absent {} .
RestartPolicy = =always / =on-error / =all / =never .
The valid restart policies are:
-
always
: Whether the process terminates normally or abnormally, restart it without affecting any peer processes within the service. -
on-error
: If the process terminates normally, leave everything alone; if it terminates abnormally, restart it without affecting peers. -
all
: If the process terminates normally, leave everything alone; if it terminates abnormally, restart the whole daemon (all processes within theDaemonservice
). -
never
: Treat both normal and abnormal termination as normal termination; that is, never restart, and enter statecomplete
even if the process fails.
Speaking Syndicate Network Protocol via stdin/stdout
By default, the syndicate-server
program assumes nothing about the information to be read and
written via a subprocess's standard input and standard output. This can be overridden with a
protocol
entry in a FullDaemonProcess
specification. (Standard error is always considered
to produce information to be put in the system logs, however.)
ProtocolField =
/ @present { protocol: Protocol }
/ @invalid { protocol: any }
/ @absent {} .
Protocol = =none / =application/syndicate / =text/syndicate .
The available options for protocol
are:
-
none
: the standard input of the subprocess is connected to/dev/null
, and the standard output and standard error are logged. -
application/syndicate
: the subprocess standard input and output are used as a binary syntax Syndicate network protocol relay. Standard error is logged. The subprocess is expected to make some entity available to the server via initial oid 0. The server reflects this expectation by automatically placing a service object record into the dataspace alongside thedaemon
record defining the subprocess. -
text/syndicate
: as forapplication/syndicate
, but Preserves' text syntax is used instead of binary syntax.
Specifying subprocess environment variables
By default, the Unix process environment passed on to subprocesses is not changed. Supplying
clearEnv
and/or env
keys alters this behaviour.
ClearEnv =
/ @present { clearEnv: bool }
/ @invalid { clearEnv: any }
/ @absent {} .
ProcessEnv =
/ @present { env: { EnvVariable: EnvValue ...:... } }
/ @invalid { env: any }
/ @absent {} .
EnvVariable = @string string / @symbol symbol / @invalid any .
EnvValue = @set string / @remove #f / @invalid any .
Setting clearEnv
to #t
causes the environment to be emptied before env
is processed and
before the subprocess is started. The env
key is expected to contain a dictionary whose keys
are strings or symbols and whose values are either a string, to set the variable to a new
value, or #f
, to remove it from the environment.
Setting the Current Working Directory for a subprocess
By default, each subprocess inherits the current working directory of the syndicate-server
program. Setting a dir
key to a string value in a FullDaemonProcess
overrides this.
ProcessDir =
/ @present { dir: string }
/ @invalid { dir: any }
/ @absent {} .
Notes
The FullProcess
type is split out in order for it to be able to be
reused outside the specific context of a daemon process.