Finalmente tive a oportunidade e a necessidade de trabalhar com isso sozinho. Minha solução requer suporte para a opção fd
para StandardOutput=
, que está disponível no (pelo menos) systemd versão 232 mas não na versão 215.
Existem três serviços e dois FIFOs. Juntos, eles criam o pipeline input | filter | output
e qualquer parte do pipeline pode ser reiniciada individualmente sem perda de dados.
O processo input
grava em um FIFO do qual filter
lê, que por sua vez grava em um FIFO que output
lê.
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