Finally had the opportunity and need to work through this myself. My solution requires support for the fd
option to StandardOutput=
, which is available in (at least) systemd version 232 but not in version 215.
There are three services and two FIFOs. Together they create the pipeline input | filter | output
, and any part of the pipeline can be individually restarted without data loss.
The input
process writes to a FIFO from which filter
reads, which in turn writes to a FIFO that output
reads.
input.service
[Unit]
Description=The input process
Requires=filter.socket
After=filter.socket
Wants=filter.service output.service
[Service]
TimeoutStartSec=infinity
Sockets=filter.socket
StandardInput=null
StandardOutput=fd:filter.socket
StandardError=journal
ExecStart=/path/to/input
Restart=always
RestartSec=5s
[Install]
WantedBy=multi-user.target
filter.service
[Unit]
Description=The filter process
Requires=filter.socket output.socket
After=filter.socket output.socket
[Service]
TimeoutStartSec=infinity
Sockets=filter.socket
Sockets=output.socket
StandardInput=fd:filter.socket
StandardOutput=fd:output.socket
StandardError=journal
ExecStart=/path/to/filter
Restart=always
RestartSec=5s
filter.socket
[Unit]
Description=Filter process reads from this
[Socket]
ListenFIFO=/run/filter
SocketMode=0600
RemoveOnStop=false
output.service
[Unit]
Description=The output process
Requires=output.socket
After=output.socket
[Service]
TimeoutStartSec=infinity
Sockets=output.socket
StandardInput=fd:output.socket
StandardOutput=journal
StandardError=journal
ExecStart=output
Restart=always
RestartSec=5s
output.socket
[Unit]
Description=Output process reads from this
[Socket]
ListenFIFO=/run/output
SocketMode=0600
RemoveOnStop=false