5.2 Communication

The (shepherd comm) module provides primitives that allow clients such as herd to connect to shepherd and send it commands to control or change its behavior (see actions of services).

Currently, clients may only send commands, represented by the <shepherd-command> type. Each command specifies a service it applies to, an action name, a list of strings to be used as arguments, and a working directory. Commands are instantiated with shepherd-command:

procedure: shepherd-command action service [#:arguments ’()] [#:directory (getcwd)]

Return a new command (a <shepherd-command>) object for action on service.

Commands may then be written to or read from a communication channel with the following procedures:

procedure: write-command command port

Write command to port.

procedure: read-command port

Receive a command from port and return it.

In practice, communication with shepherd takes place over a Unix-domain socket, as discussed earlier (see Invoking shepherd). Clients may open a connection with the procedure below.

procedure: open-connection [file]

Open a connection to the daemon, using the Unix-domain socket at file, and return the socket.

When file is omitted, the default socket is used.

The daemon writes output to be logged or passed to the currently-connected client using local-output:

procedure: local-output format-string . args

This procedure should be used for all output operations in the Shepherd. It outputs the args according to the format-string, then inserts a newline. It writes to whatever is the main output target of the Shepherd, which might be multiple at the same time in future versions.

Under the hood, write-command and read-command write/read commands as s-expressions (sexps). Each sexp is intelligible and specifies a protocol version. The idea is that users can write their own clients rather than having to invoke herd. For instance, when you type herd status, what is sent over the wire is the following sexp:

  (version 0)
  (action status) (service root)
  (arguments ()) (directory "/data/src/dmd"))

The reply is also an sexp, along these lines:

(reply (version 0)
       (result (((service …) …)))
       (error #f) (messages ()))

This reply indicates that the status action was successful, because error is #f, and gives a list of sexps denoting the status of services as its result. The messages field is a possibly-empty list of strings meant to be displayed as is to the user.