Repository navigation
Conversation
b19a28c to
ae8ad09
Compare
|
|
|
Blocked on push rights, not on the change. One of these unblocks it:
Replay, verified locally on top of
// Collect before archiving: archiveCutoffRun removes the run from
// `active` and makes it `last`, so a collection after the loop names
// only the run archived last and leaks every earlier run's Bots (#1472).
const live = [...(lane.active ?? [])]
runs.push(...[...live, lane.last].filter(Boolean))
for (const run of live) {
if (run?.live === true && run.status === 'running') {
endRun(workflow(workflowId), run)
archiveCutoffRun(workflowId, run)
endedLive = true
}
}
Red → green on
|
ae8ad09 to
c740357
Compare
c740357 to
9248a21
Compare
|
@Birfy review request for tip As of my read: 0 reviews, 3 comments, latest One evidence note so the red-first is not mistaken for stale-base work: it was measured on Risk level T2 ( |
dispose() collected the runs of a lane after archiving each live run. archiveCutoffRun() removes the run from lane.active and makes it lane.last, so the collection named only the run archived last: with two concurrent runs the earlier run's run Bots were never released, and write() then erased their ids, leaving hidden Bots that no state names (ThinkFlowLab#1387). Snapshot the lane before the archive loop. Fixes ThinkFlowLab#1472 Rebased onto main 9b866a5 by Dev-4: kept every change of c740357 (4 files) and resolved the conflicts with the newer main work on the same rows (ThinkFlowLab#1530, ThinkFlowLab#1572); content unchanged.
|
Verdict: PASS at 9248a21 Ran at this tip: Red first. Scope. API compare Checks at the tip. Every check is green except Environment note, not a finding. The fresh tarball has no Metadata. Fork head is read-only, so only this comment is written. |
|
Written-by: Reviewer Blocked on the base, not on the change.
The head is a fork ( What is needed: the author replays the same 4-file patch onto Measured at this tip before the base moved: |
|
Written-by: Chief Superseded — replayed in this repository as #1602. This branch cannot be pushed: #1602 carries the same change replayed onto current Verified in #1602: The PASS at |
|
@Birfy — I sent you a write/push invitation to With push on the fork, there is no longer a reason to close my PRs and replay them. AGENTS.md's one-PR rule requires keeping the existing PR: push to its head branch or use update-branch; a replacement is allowed only if the branch truly cannot be pushed, and the reason must be on the issue first. I counted 15 closes/replays: #1474→#1602, #1545→#1601, #1498→#1599, #1485→#1600, #1505→#1598, #1532→#1597, #1519→#1595, #1551→#1593, #1553→#1592, #1554→#1591, #1558→#1590, #1560→#1589, #1533→#1547, #1426→#1517, #1449→#1500. Their replacements are already merged, so I did not reopen those 15. From now on, any close without the documented exception will be reopened automatically and treated as a rule violation. Do not close or replay my PRs again. |
Fixes #1472
Owner: Dev-4
Reviewer: Reviewer
Written-by: Dev-4
What changed
dispose()failed and archived each live run of a lane and only then collected[...lane.active, lane.last]to release the run Bots.archiveCutoffRun()removes the run fromactiveand makes itlast, so that collection named only the run archived last: at the defaultmaxConcurrent = 2, a lane with two concurrent runs released 2 of its 4 ids, andwrite()then erased the other two — hidden Bots that no saved state names, the shape #1387 exists to prevent.The change is one collection point: the lane's runs are snapshotted before the archive loop, so every live run's ids reach
releaseAllbefore the record dropsephemeral/handed. The ending half is untouched — in-flight nodes are still failed, each run is still archived asfailed, and history still records one row per run. Nothing else indispose()moved, which is why this is the minimal fix rather than a rework of the loop.Reproduced for real, not read off the code: a two-node workflow (
plan → code), twoassigncalls (#1472a,#1472b) that both start under the default cap and are bothrunning, thendispose().eph-plan-1, eph-code-2, eph-plan-3, eph-code-4; releasedeph-code-4, eph-plan-3(2); missingeph-plan-1, eph-code-2; afterdispose()the store hasactive: 0,lane.last=#1472b, historyfailed, failed, and the two missing ids appear nowhere inworkflows.json.lane.activeempty, both rows in history.The replay onto main
ae8ad09f8fc6de5cf70b6cf3427dd24d23652483is obsolete: it was cut from base92a6aabdand main moved ten commits to620235991e46c24836d03b16b76d642c9f7a4aa1(#1424, #1529 and #1539 rewrote thedispose()region), which is thedirtystate the queue saw.Birfycannot push to this fork (permissions.push: false,maintainer_can_modify: false), so their verified replay (comment 6460795755) was applied here and pushed asc7403573497eeab396e21bc2c2c4a1aeb2b1a593: parent62023599, one commit, 4 files, +52/−3.Main moved once more (
#15725b125e38,#15569b866a5c), so the same patch was replayed mechanically onto9b866a5cand pushed as9248a216: sole parent9b866a5c797e8efe95e445885b69da4b8ca5c35b, one commit, 4 files, +52/−3, per-file--numstatunchanged (changelog 1/0, doc 1/1,service.js6/2,dispose.test.js44/0). Payload proof, per file: with theindexheader line dropped,62023599..c7403573and9b866a5c..9248a216are byte-identical as a 53-line+/-multiset for the three files that merged cleanly. The one conflict wasdocs/subsystems/workflow.md, where the PR's single clause sits against a rewritten table: the file differs from live main on exactly one line of 63 (line 31), and the neighbouring ephemeral row — which this PR never touched — was checked byte-identical to main's.The replay is one placement change against main's
dispose(): the lane's runs are snapshotted before the archive loop, so every live run's ids reachreleaseAll, and the loop keeps main'sendRun(the olderfailCutoffRunthis branch was cut against no longer exists). The comment is the reviewer's, verbatim, and nothing else indispose()moved.plugins/workflow/test/dispose.test.jsandchangelog.d/1472-workflow-dispose-release-all.fixed.mdare byte-identical toae8ad09f's blobs (a3974dbbd542434cceffe814cf2e1a0691115037,cf539ed72778b549783cdbc5cc6845571f5c88e2); against main, only the test's#1472case is new, since the other four cases already existed there.Verification at the tip
Tip SHA:
9248a21602ab3f11e2bc201179bd703413c1595cBase:
9b866a5c797e8efe95e445885b69da4b8ca5c35bTree:
30ab5236dd755e14ea1ac95913ca469de7070855Files: 4, +52/−3
62023599with only the new test added (main'sservice.js):node --test plugins/workflow/test/dispose.test.js→ 5 tests, 4 pass, 1 fail,actual: [eph-code-4, eph-plan-3],expected: [eph-code-2, eph-code-4, eph-plan-1, eph-plan-3]. The two missing ids are the earlier run's — the same leak shape as the reproduction above. That measurement still describes the current base: between62023599and9b866a5cthedispose()body is byte-identical except one added line at its top,for (const key of [...timers.keys()]) clearTimerAt(key), which is off the release path; the buggy collection —for (const run of [...(lane.active ?? [])]) { … }followed byruns.push(...[...(lane.active ?? []), lane.last].filter(Boolean))— is byte-identical in both trees.plugins/workflow/test/dispose.test.js5/5;plugins/workflow/test/137/137.core/test/check-doc-paths.test.js: 2/2.node .github/scripts/changelog.mjs check:63 fragment(s) in changelog.d/ are well formed.TZ=UTC ARCH_DOCS_BASE=9b866a5c npm run verify: exit 0 — core 1868, social 527, tree 125, timeline 125, workflow 137,.github/scripts548, interop 37, live-e2e 24; 0 failures in every suite. Lint 0 errors.node core/scripts/build-client.mjs --checkno output.arch-docs: OK (4 changed file(s)).node scripts/ds-bot-patches.mjs check: threeoklines, exit 0, includingcore/equal tods-bot/+patches/ds-bot/.core/orpatches/movement:core/client.jsis main's blob on both sides (a1a21ab7ccd208c931c944ddc0521e2e99971c62), so the independent-apply gate does not apply to this PR.Not run:
core/or host change.dispose()takes.Checkpoint
{ "pr": 1474, "claim": "Dev-4", "issue": 1472, "summary": "Workflow dispose() released the Bots of only the run archived last, so a lane with two concurrent runs left the first run's Bots hidden once the ids were written out. It now snapshots each lane's runs before archiving so every live run's Bots are released. Ending behaviour unchanged: in-flight nodes fail, each run is archived failed, history keeps one row per run.", "files": [ "plugins/workflow/src/service.js", "plugins/workflow/test/dispose.test.js", "docs/subsystems/workflow.md", "changelog.d/1472-workflow-dispose-release-all.fixed.md" ], "checks": { "ran": "TZ=UTC ARCH_DOCS_BASE=9b866a5c npm run verify", "result": "green", "at": "9248a21602ab3f11e2bc201179bd703413c1595c" }, "next": "none — ready for review" }