Repository navigation
fix(runner): preserve notify readiness across child scopes - #116
Bacongineer wants to merge 1 commit into
Conversation
Goal: Keep a notify service ready and its ordered dependents startable while the leased engine lives in its own scope. How: Give the child a private Unix datagram socket and relay notifications from the service-owned wrapper to the original manager socket. Key details: Preserve datagram payloads and descriptor rights, including barriers and stored descriptors. Receive rights close-on-exec, clean private state on shutdown and failed starts, and surface transport failures through the existing boundary-aware drain path. Cover leased and unleased sender identity, setup, cleanup, descriptor forwarding, and pending errors at child exit.
|
Thanks for catching this. You were right, and I reproduced it here: a I went with a smaller fix in #117. When Do you run a setup where the engine needs its own scope and also sits under a notify service? If so, #117 misses it and I want to know. If not, I'll close this one once #117 merges. Your native systemd fixture notes saved me time checking this, thank you. |
|
Thanks for reproducing this. I agree that #117 is the better solution for our current setup. To answer your question directly: no, we do not currently require an engine to have its own separate scope while also running under a For context, Kodi is the GPU lease holder in our playback setup. SVP is a tracked helper, not another lease holder, ordered after Kodi's service and tied to its lifetime. The unit runs I reviewed #117's change. Keeping the child in the service cgroup when I understand the trade-off: notify tenants do not get #112's escaped-child scope attribution. For our current requirements, that does not justify maintaining #116's relay instead of taking your smaller fix. |
|
Closing in favor of #117, now merged. Thanks again for finding this and for the clear repro. |
Problem
After #112, a child launched by
berth runcan live in a sibling systemd scope. Itssd_notifysender credentials then belong to that scope rather than the originalType=notifyservice. Even withNotifyAccess=all, the service can remainactivatingwhile its child is already running, and ordered helper services cannot start.Change
SCM_RIGHTS, including synchronous notification barriers andFDSTORE. Receive descriptors close-on-exec, close received copies after forwarding, and reject truncated payloads or ancillary data.NOTIFY_SOCKET; other platforms retain their existing behavior.This does not emit
READY=1on the child's behalf, change unit ordering, weakenNotifyAccess, remove the engine scope, add configuration, or add dependencies.Verification
The sender-attribution, pending-error-at-exit and cleanup-failure regressions each failed before their corresponding correction and passed afterward. Protocol tests cover leased/unleased sender identity, absolute/abstract destination sockets, barriers, stored-descriptor contents, malformed setup, failed starts, truncation, transport failure and idempotent cleanup.
Local checks passed on the committed tree:
go build ./..., formatting andgo vet ./...go test -timeout 0 -count=1 ./...go test -race -timeout 0 -count=3 ./internal/runner ./internal/sysdgolangci-lintinvocationA standalone built executable also passed a CPU-only native user-service lifecycle fixture. The owning notify service reached
activebefore its ordered helper started. Helper lifetime, signal/stop cleanup, broker reattachment and transaction recovery, and fast cold-start ComfyUI completion/release passed. Fixture state was cleaned and protected process identities stayed unchanged.That native check matters because Go tests bypass real systemd scope creation under
testing.Testing(). It used isolated CPU stand-ins, not real GPU applications or model workloads. No production deployment is part of this PR.