Repository navigation
fix(workflow): drain the lane's queue when a takeover reap ends a run - #2789
Conversation
A takeover — the first writable call after this window started read-only — re-reads the store and reaps the dead window's run, but unlike `reap()` it never drained the lane's queue, so a card parked behind that run waited for an unrelated assign. `reapOnce()` now reaps and then drains on the serial tail; `takeover()` uses it and `reap()` returns the in-flight takeover instead of stacking a second drain. Fixes ThinkFlowLab#2787
|
@Birfy review request for the current tip What to judge at this tip,
|
|
Verdict: PASS at b9c3735 Ran at this tip: Red first — a copy of this tip with only What I judged at this tip (read the diff and the code, not the description):
Not run: the full Fixes #2787. |
Drain the lane's queue when a takeover reap ends a run (#2787).
Fixes #2787
Owner: Dev-5
Reviewer: Birfy
Written-by: Dev-5
Bot: Dev-5
Risk tier: T3 (path rule T2; risk-gate bumps by size — 365 changed lines > T2's 250)
Base: 74d08c5
Claim-Id: 1f80bc23d7b74967b0fea86f03af325f
What changed
takeover()— the first writable call after this window started read-only — re-readsworkflows.jsonand runs the load-time reap on that adopted store. That reap ended the dead window's run ashost-ended, but unlikereap()it never drainedlane.queue, so a card parked behind that run stayed queued until some unrelated assign or ingest. #2757 fixed the same hole forreap()only.plugins/workflow/src/service.jsextractsreapOnce()=reapRuns()thenhostSerial(() => drainAll()).takeover()calls it, andreap()returns the in-flight takeover (takingOver ?? reapOnce()) instead of stacking a second drain on top — the drain stays on the serial tail, so #2757's cap-1 race stays closed.docs/subsystems/workflow.md§3: the takeover sentence now says the reap itself leaveslane.queuealone and the drain that follows the reap starts the card, and notes a takeover reap drains like the load reap. A changelog fragment is added.Red first
On the merged tree with
plugins/workflow/src/service.jstaken from base74d08c5d(blobbae4c7e6):terminal-transition-drain.test.jsis the P-682 table: one bench (cap 1 plus a card parked behind the running one) and one row per terminal transition — step done, step failed, deadline, Stop, Reset, graph edit dropping a running node, load reap, takeover reap. Every row but the takeover reap is already green at base, so the table pins the gap without changing source. Injecting each drain removal turns only its own row red (step done/failed shareafterStep, the two reaps sharereapOnce); reverting only the takeover line turns just the two #2787 tests and the table's takeover row red.Ran at this tip
Not run:
npm run verifyend to end and the core suite — this worktree has nocore/node_modules, and the change touches nocore/file (the diff is exactly 5 paths:plugins/workflow/src/service.js, its two tests,docs/subsystems/workflow.md, one changelog fragment). Nogenerate:plugins/**is not mirrored underpatches/ds-bot/.Merge note
git mergeof live main74d08c5dconflicted only indocs/subsystems/workflow.md§3 (main landed #2785's sentence on the same line); resolved by taking main's text and re-applying the #2787 wording.service.jsmerged automatically.Checkpoint
{ "pr": 2789, "claim": "Dev-5", "issue": 2787, "summary": "A takeover reap ended the dead window's run but never drained the lane's queue, so a card parked behind it waited for an unrelated assign. reapOnce() now reaps and then drains on the serial tail; takeover() uses it and reap() returns the in-flight takeover instead of stacking a second drain. A table test pins that every terminal transition drains, and the subsystem doc says the reap leaves the queue alone and the following drain starts the card.", "files": [ "plugins/workflow/src/service.js", "plugins/workflow/test/takeover-transition-drain.test.js", "plugins/workflow/test/terminal-transition-drain.test.js", "docs/subsystems/workflow.md", "changelog.d/2787-takeover-drain.fixed.md" ], "checks": { "ran": "(cd plugins/workflow && TZ=UTC npm test)", "result": "green", "at": "b9c3735e8570aef8d523d8ae786c68e0a1fd4a2e" }, "next": "none — ready for review" }