fix(issue-18): drain the previous heartbeat timer before handing over its pidfile
Review round 3 (planner-reviewer-codex-01, NOT PASS R3 at7e1d3f0): start_timer stopped a running timer with a bare TERM and overwrote the only pidfile. A beat the old timer had already admitted - seq taken, recorded on disk, held at the wire - stayed alive but undiscoverable, so a later terminal publish drained only the replacement and the old beat could still put a retained `running` on the broker after `completed`. - heartbeat.start_timer: stop_timer(drain=MAM_HEARTBEAT_DRAIN_S). The old timer is drained or killed, and confirmed gone, before the pidfile names the new one. A terminal publish racing the replacement either drains the same old pid or meets a new timer whose beats the barrier refuses. - test: an old timer held at the wire after admission is replaced, then the job completes; the old timer is gone before the handover and nothing it held follows the terminal (fails on7e1d3f0). - docs: MESSAGING 4.3 no longer says any state resets the idle clock; MESSAGING 2.5 and VERSIONS state the replacement rule; test count 26. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HCGpJXhSZasJLU38ksDghe
This commit is contained in:
1 parent
7e1d3f0815
commit
ab842f1ee0
4 files changed
+98
-5
No files matched your search
@@ -258,10 +258,14 @@ def start_timer(job_id: str, registry_dir: str, interval: int,
|
||||
|
||||
A timer that already runs for the job is stopped first: a second `started`
|
||||
for the same job (a retry of the same command) must not double the rate.
|
||||
It is drained as at a terminal event - and killed if it does not exit -
|
||||
before its pidfile is handed over (review round 3, codex R3): a beat it had
|
||||
already admitted would otherwise still reach the wire after a terminal
|
||||
publish that can find only the new timer through the pidfile.
|
||||
``watch_pid`` binds the timer to a process (default: the nearest agent-CLI
|
||||
ancestor of this process, if any); 0 disables the watch explicitly.
|
||||
"""
|
||||
stop_timer(job_id, registry_dir)
|
||||
stop_timer(job_id, registry_dir, drain=drain_seconds())
|
||||
if watch_pid is None:
|
||||
watch_pid = nearest_agent_cli_ancestor()
|
||||
cmd: List[str] = [python or sys.executable, "-m", "lib_py.delegation.heartbeat",
|
||||
|
||||
Reference in new issue
Block a user