fix(issue-50): a waiter whose own attempt is already running answers clear, not superseded
The registry wait judged its record by one rule: not this attempt's pending record in this session -> superseded (redispatched, moved or closed by someone else). That also caught the record's own `started` landing before the prompt went out - the Issue #14 registry ack winning over an unreachable broker, as test_issue30_stall_watch_stop acknowledges at registration - and the wrapper left on exit 5 instead of its broker_unavailable path (rc 3). A record that is running under this attempt's token in this session is this attempt's own progress: the waiter answers `clear` at once, writes no admission and starts no hold. Another token, another session or a terminal status stay `superseded` (review 55219be1 R1 unchanged). Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
1 parent
7844ae2c5f
commit
d50610c1ab
2 files changed
+42
-3
No files matched your search
@@ -334,6 +334,16 @@ def _own(rec: Optional[dict], token: Optional[str], session: str) -> bool:
|
||||
and _bare(str(rec.get("agent_session") or "")) == _bare(session)
|
||||
|
||||
|
||||
def _started_own(rec: Optional[dict], token: Optional[str], session: str) -> bool:
|
||||
"""This attempt's record, in this session, already `running`: its own
|
||||
`started` landed before the prompt went out (the registry ack of Issue
|
||||
#14 wins over an unreachable broker; a test that acknowledges at
|
||||
registration). Nothing was redispatched, moved or closed by someone else
|
||||
- there is just nothing left to wait for."""
|
||||
return bool(rec) and bool(token) and rec.get("status") == "running" and rec.get("dispatch_token") == token \
|
||||
and _bare(str(rec.get("agent_session") or "")) == _bare(session)
|
||||
|
||||
|
||||
def _merge_own(registry_dir: str, job_id: str, token: Optional[str], session: str, source: str, fields: dict,
|
||||
guard=None) -> bool:
|
||||
"""One merge through the engine, committed only while the record re-read
|
||||
@@ -434,7 +444,9 @@ def wait_open_jobs(a: argparse.Namespace) -> str:
|
||||
and its admission is committed (_admit); `busy <ids>` when the bound runs
|
||||
out first; `superseded` once the record is not this attempt's pending one
|
||||
in this session any more (redispatched, moved, closed by someone else) -
|
||||
nothing is written or closed then, the record is its owner's. The bound
|
||||
nothing is written or closed then, the record is its owner's; `clear`
|
||||
at once, with no admission, when it is this attempt's and already
|
||||
running (_started_own). The bound
|
||||
is min(--wait-s, this job's remaining wall clock). The identity is pinned
|
||||
at the start: --dispatch-token (the token the wrapper read for this
|
||||
attempt), else the record's token read once. Every DISPATCH_SIGNAL_EVERY s
|
||||
@@ -450,8 +462,9 @@ def wait_open_jobs(a: argparse.Namespace) -> str:
|
||||
last_signal = None
|
||||
while True:
|
||||
now = _now()
|
||||
if not _own(_load_record(a.registry_dir, a.job), token, a.agent_session):
|
||||
return "superseded"
|
||||
rec = _load_record(a.registry_dir, a.job)
|
||||
if not _own(rec, token, a.agent_session):
|
||||
return "clear" if _started_own(rec, token, a.agent_session) else "superseded"
|
||||
live, stale = open_jobs(a.registry_dir, a.agent_session, a.job, now)
|
||||
for other, reason in stale:
|
||||
if other not in reported:
|
||||
|
||||
Reference in new issue
Block a user