dea56e4bcd
Type=forking with no PIDFile left MainPID=0, so systemd read a crashed tmux server as a clean exit and Restart=on-failure never fired. tmux -D runs the server in the foreground, which gives systemd the real pid. -D also turns exit-empty off, so the synthetic orchestra-runtime session is no longer needed to hold the server open past its last agent pane. Nothing else in the tree referenced that session. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011xsXyr5J1RACo71YeKG3Pu
45 lines
1.9 KiB
Desktop File
45 lines
1.9 KiB
Desktop File
# The tmux execution runtime, owned separately from the worker.
|
|
#
|
|
# The worker used to spawn this server implicitly on its first tmux command,
|
|
# which put the server and every agent pane inside the worker unit's cgroup.
|
|
# Restarting the worker then destroyed the sessions it was restarting to
|
|
# manage: a deploy killed the run it was deploying for, and F16's missing-pane
|
|
# branch fired on deployment rather than on real execution-runtime loss.
|
|
#
|
|
# KillMode does not fix that. Under `mixed` systemd still sends the final
|
|
# SIGKILL to whatever remains in the cgroup, and `process` only encodes
|
|
# accidental orphaning. The runtime has to be a service of its own.
|
|
#
|
|
# Lifecycle this gives you:
|
|
# systemctl restart orchestra-worker -> panes survive, worker reconciles
|
|
# systemctl stop orchestra-tmux -> panes die, deliberately
|
|
#
|
|
# User MUST match orchestra-worker.service. The socket lives under
|
|
# /tmp/tmux-$UID, so a mismatch leaves the worker talking to a different
|
|
# server, or to none.
|
|
[Unit]
|
|
Description=Orchestra tmux execution runtime
|
|
After=network.target
|
|
|
|
[Service]
|
|
# -D runs the server in the foreground, so systemd tracks the real server pid
|
|
# as MainPID. Type=forking left MainPID=0, and systemd then read a crashed
|
|
# server as a clean exit, which Restart=on-failure ignores.
|
|
#
|
|
# -D also turns exit-empty off, so the server outlives its last agent pane.
|
|
# That removes the need for a synthetic idle session to hold it open.
|
|
#
|
|
# The socket name is the worker's tmux_socket for this harness (-L, not -S).
|
|
# Keep the two in step; the worker does not create the server any more.
|
|
Type=simple
|
|
User=kami
|
|
ExecStart=/usr/bin/tmux -D -L orchestra
|
|
# The runtime coming back empty is honest: the panes are gone either way, and
|
|
# F16 observes that as real execution loss. Refusing to restart would instead
|
|
# block every later launch until an operator noticed.
|
|
Restart=on-failure
|
|
RestartSec=1
|
|
|
|
[Install]
|
|
WantedBy=multi-user.target
|