# ECP-0122: Publisher Source Locks And Cgroup Cleanup Status: Draft ## Problem statement LA channels disappeared when stale proof/archive publisher helpers kept HDHomeRun tuner HTTP streams open after the managed publishers restarted. The restarted publishers saw `503 Service Unavailable` from the tuners, stopped refreshing the public stream directory, and the guide expired to empty. ## Constraints - A publisher restart must not leave child media processes holding tuners. - A duplicate publisher on the same node must not open the same physical source URL. - Keep rollback simple and deployment-owned; no source-device firmware or manual tuner reset should be required for normal recovery. ## Decision The NixOS publisher wrapper now takes a non-blocking per-source lock under `/run/every-channel/source-locks` before launching `ec-node`. If another managed publisher on the same node is already reading that input URL, the duplicate launch logs and skips instead of opening a second tuner stream. Publisher and archive worker services also set explicit `KillMode=control-group`, `TimeoutStopSec=10s`, and `SendSIGKILL=true`, and archive auto-workers terminate tracked children on shutdown before systemd's cgroup cleanup runs. The async `wt-publish` and `nbc-wt-publish` ffmpeg children are marked kill-on-drop so cancelled Rust futures do not strand encoder children. ## Alternatives considered - Rely on operator cleanup only. Rejected because the failure silently empties the public guide after TTL expiry. - Run duplicate publishers for redundancy. Rejected because OTA tuner capacity is the scarce resource; redundancy should happen after one source read, via publisher fanout and relay mirroring. - Add only systemd cgroup cleanup. Rejected because it does not prevent two managed units from intentionally opening the same source at the same time. ## Rollout / teardown plan Deploy the NixOS module update to every publisher node. Confirm no stale proof/archive helpers remain, all managed publisher units are active, and `/api/public-streams` lists the expected channels. Rollback is reverting this module change and redeploying; source locks are runtime files under `/run` and disappear on reboot.