emrg: daemon single-instance admission + truthful old-pid wait (rant 2026-08-18T12:49:09) - #841
Merged
Merged
Conversation
…2026-08-18T12:49:09) Windows multi-client (GUI + TUI, possibly different installs) stale-restart storms leave multiple emrg.server processes on different ports, interrupting in-flight evolution cycles for hours. Two fixes: 1. Server admission (daemon.py): before the pid-file check, probe the port file — if a live daemon already answers, refuse to start a duplicate. Stale-restart sequences can leave the pid file missing while an old daemon is still alive; the pid check alone then lets a second instance bind a new port (observed: 4 coexisting processes). 2. Client wait (daemon_manager.py): the old daemon must be TRULY dead before the port file is removed. cleanup_server() previously deleted the port file first, so is_running() (a port-file probe) returned False instantly and a new daemon spawned while the old one was still shutting down. Now waits on the old PID (POSIX os.kill(pid,0) probe; Windows keeps the port probe — os.kill(pid,0) would TerminateProcess there), SIGKILL fallback, then cleanup_server() only after death. Tests: admission positive + negative (serve refuses duplicate / proceeds when no live daemon), restart waits-for-death ordering, SIGKILL fallback on stuck pid. Agent.md pytest count 933→937.
argszero
commented
Aug 18, 2026
argszero
left a comment
Owner
Author
There was a problem hiding this comment.
✅ LGTM — cycle 709 (1/3). CI test + test-windows PASS (32105124982). Local: pytest 936+1 (937 collected), GUI 257/257, import + CLI green. Admission probe + truthful old-pid wait verified with 4 new tests (both daemon.py and daemon_manager.py paths).
…ge + #841's 4 tests)
argszero
commented
Aug 18, 2026
argszero
left a comment
Owner
Author
There was a problem hiding this comment.
✅ LGTM — cycle 711 (3rd). Head 96ca181 (conflict-resolved), CI test + test-windows PASS (32106785798), MERGEABLE/CLEAN. Three consecutive LGTMs (cycles 709/710/711), no ❌ — merging. This lands the Windows multi-instance daemon fix (rants 12:49:09 + 14:01:10).
argszero
added a commit
that referenced
this pull request
Aug 18, 2026
v0.2.47 -> v0.2.48 across 8 files / 9 refs (standard release bump): - emrg/__init__.py, pyproject.toml, uv.lock (emrg entry) - emrg/gui/package.json + package-lock.json (x2) - packaging/build-runtime.sh, make-installer.sh, make-run-installer.sh Covers 4 commits since v0.2.47: #839 (TUI exit clear-screen), #840 (GUI countdown refresh), #841 (daemon single-instance admission), #842 (GUI task last-run meta). Rant 2026-08-18T14:46:47. Co-authored-by: EMRG Evolution <emrg@argszero.dev>
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.
Windows multi-client daemon coexistence (observed 2026-08-18): with GUI + TUI resident, stale-restart storms left 4
python -m emrg.serverprocesses on different ports and kept killing in-flight evolution cycles (a cycle running 399+ tool-loop messages died at 11:14:15 to a stale-pid restart, then restarted from the same half-finished worktree state — never completing).Fix 1 — daemon-side single-instance admission (
emrg/server/daemon.py)is_server_running_sync), log and refuse to start a duplicate.Fix 2 — client-side truthful old-pid wait (
emrg/client/daemon_manager.py)cleanup_server()previously deleted the port file BEFORE the wait, sois_running()(a port-file probe) returned False instantly → new daemon spawned while the old one was still shutting down.os.kill(pid, 0)probe; Windows keeps the port probe —os.kill(pid, 0)would TerminateProcess there) → SIGKILL fallback after 10s →cleanup_server()only after death is confirmed.Tests (4 new)
test_serve_refuses_duplicate_when_daemon_alive— admission positive pathtest_serve_proceeds_when_no_live_daemon— admission negative pathtest_restart_waits_until_old_pid_dead_before_cleanup— wait orderingtest_restart_force_kills_stuck_old_pid— SIGKILL fallbackLocal: pytest 936 passed + 1 skipped (937 collected), GUI 257/257, import + CLI green. Agent.md pytest count 933→937.