Services and service dependencies

Assertions in the main $config dataspace are the means Synit uses to declare services and service dependencies.

Service are started "gracefully", taking their dependencies into consideration, using require-service assertions; upon appearance of require-service, and after dependencies are satisfied, a run-service assertion is automatically made. Services can also be "force-started" using run-service assertions directly. Once all run-service assertions for a service have been withdrawn, services shut themselves down.

Example: Docker daemon

As a concrete example, take the file /etc/syndicate/services/docker.pr, which both defines and invokes a service for running the Docker daemon:

<require-service <daemon docker>>
<depends-on <daemon docker> <service-state <milestone network> up>>
<daemon docker "/usr/bin/dockerd --experimental 2>/var/log/docker.log">

This is an example of the scripting language in action, albeit a simple one without use of variables or any reactive constructs.

  • The require-service assertion instructs syndicate-server to solve the dependencies for the service named <daemon docker> and to start the service running.

  • The depends-on assertion specifies that the Docker daemon requires the network milestone (configured primarily in network.pr) to have been reached.

  • The daemon assertion is interpreted by the built-in external service class, and specifies how to configure and run the service once its dependencies are ready.

Details

A few different kinds of assertions, all declared in the service.prs schema, form the heart of the system.

Assert that a service and its dependencies should be started

RequireService = <require-service @serviceName any>.

Asserts that a service should begin (and stay) running after waiting for its dependencies and considering reverse-dependencies, blocks, and so on.

Assert that a service should start right now

RunService = <run-service @serviceName any>.

Asserts that a service should begin (and stay) running RIGHT NOW, without considering its dependencies.

The built-in handler for require-service assertions will assert run-service automatically once all dependencies have been satisfied.

Declare a dependency among services

ServiceDependency = <depends-on @depender any @dependee ServiceState>.

Asserts that, when depender is require-serviced, it should not be started until dependee has been asserted, and also that dependee's serviceName should be require-serviced.

Convey the current state of a service

ServiceState = <service-state @serviceName any @state State>.
State = =started / =ready / =failed / =complete / @userDefined any .

Asserts one or more current states of service serviceName. The overall state of the service is the union of asserted states.

A few built-in states are defined:

  • started - the service has begun its startup routine, and may or may not be ready to take requests from other parties.

  • started + ready - the service has started and is also ready to take requests from other parties. Note that the ready state is special in that it is asserted in addition to started.

  • failed - the service has failed.

  • complete - the service has completed execution.

In addition, any user-defined value is acceptable as a State.

Make an entity representing a service instance available

ServiceObject = <service-object @serviceName any @object any>.

A running service publishes zero or more of these. The details of the object vary by service.

Request a service restart

RestartService = <restart-service @serviceName any>.

This is a message, not an assertion. It should be sent in order to request a service restart.