Conversation
…lock scan [#58] - shared _acquire_push_lock steals locks whose owner is dead or pid-less instead of waiting out the full budget (cron push + daemon workers) - workers trap TERM/INT/HUP so a service restart no longer leaks the lock dir - worker pool slot wait capped at 1h, then reports failed - doctor: find -H so a symlinked /var/lock is actually scanned - doctor: stuck detection uses the worker enqueue stamp, not the refreshed ts - tests: push lock steal/wait cases and the symlinked lock dir scan
- skip a duplicate worker while a live one is registered for the container (reconcile sweep and the real docker event both fire on a restart) - worker EXIT trap drops the registry entry only while it still names its own pid, so a sibling worker is no longer unregistered mid-push - daemon mode takes a host-wide flock and refuses to start next to a running daemon, which used to wipe the live registry and fight it over push locks - tests: duplicate worker guard and daemon instance lock
- _prune_stale_vpk_links runs on both the push and the verify path; the egg skips its own broken-link cleanup while the daemon is authoritative - test: stale links pruned, live ones kept - trim the comment blocks added by the previous two commits
…emon restart [#58] - --daemon next to a live daemon prints pid, uptime, version and in-flight pushes, then exits 0 - --daemon restart drains in-flight pushes (5 min cap) and cycles the service - test: the stand-in worker needs a trailing ':' or bash execs sleep over itself and the argv[0] alias is lost (failed on Debian, passed on Alpine)
2 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #58, where two servers sat on "Waiting for game files" for days while
--doctorreported the host as healthy.Root cause
Both servers had a push lock directory left over from July with no owner pid in it. Every worker that touched those containers waited on that lock, so their status never left
queued. Because the status refresher keeps the timestamp fresh for as long as a worker lives, the egg read that as "the daemon is working" and waited forever instead of falling back to SteamCMD, and the doctor's stuck-state check, which measured the same timestamp, never fired either.The lock itself was never cleaned because the doctor scanned
/var/lockwithfind, and on Debian/Ubuntu that path is a symlink to/run/lockwhichfinddoes not descend into without-H. That entire cleanup had been scanning nothing.What changed
Locks
_acquire_push_lockis now shared by the cron push and the daemon workers, and takes over a lock whose owner is dead or carries no pid instead of waiting out the full budgetTERM/INT/HUPso a service restart runs their cleanup, rather than leaking the lock directory (bash skips theEXITtrap on an uncaught signal)find -H, so it actually sees the locksNo more unbounded waits
failed, which drops the server to SteamCMD instead of leaving it in limboOne worker per server, one daemon per host
flock. A hand-started second instance used to wipe the running daemon's worker registry--daemonnext to a running daemon now reports on it (pid, uptime, version, pushes in flight) instead of failing, and new--daemon restartdrains in-flight pushes before cycling the serviceCleanup and reporting
--testand--doctorbypass the GitHub CDN cache so they always see the branch as it is now; self-update keeps the plain URL since it runs from cron on every hostTesting
misc/protocol-test.shgrew five daemon-side cases: push lock steal/wait, stale link prune, duplicate worker guard, daemon instance lock, and the symlinked lock directory scan. The suite runs green on macOS and in a Debian container, as root and as a normal user. Two of the new cases were verified to fail against the old code.Confirmed on the reporter's production host: both stuck servers picked up the current build and booted normally, and a separate host was used to verify
--daemonreporting and--daemon restart.Also
The README roadmap gained two entries that came out of this: an update soak window for the automatic self-update, and signed releases as the longer-term supply-chain answer.