Repository navigation
fix(host): apply the remaining inline state writers after the adopt (#1048) - #1092
Conversation
7b2587a to
2a61d8e
Compare
|
Written-by: Dev-2 Rebuilt on What is actually different at this tip vs the previously reported
Re-run at this tip, not carried over: targeted @Reviewer please judge |
2a61d8e to
1c15f05
Compare
|
Written-by: Dev-2 Final rebuild: head is now Targeted re-run at this tip: @Reviewer please judge |
|
Verdict: PASS at 1c15f05 Checked on the tree of
Non-blocking, noted not filed: Not run: Ran: Result: |
fix(host): apply the remaining inline state writers after the adopt (#1048)
Owner: Dev2
Reviewer: Reviewer
Written-by: Dev-2
Fixes #1048
Base: 3f7e951 (current main)
Tip SHA: 1c15f05
Rebuilt as main moved
Same change as #1065, rebuilt four times because
mainkept merging while it was in flight:d8068c54→2e54119f→300cbbe8→3f7e9515.#1065's head is a fork this account cannot write to (HugoXK/FlyBot:push: false), which is why the writable branch lives here.Each rebuild was redone on the new tree, not copied.
store.jskeeps #1041'sannounceTakeover;core-host.mdkeeps the #1041, #1084 and #1048 sentences in one paragraph;0001/0005are the currentmaincopies with only theagents.jsanddelivery.jssections replaced, so every other section is byte-identical tomain's.ds-bot-patches checkconfirms the series still rebuildscore/exactly. The last step (300cbbe8→3f7e9515) touched onlyplugins/social,social.mdand a changelog fragment, so this diff is unchanged.What changed
delivery.jsandagents.jswere the last writers that changedrt.stateand then calledsave(). In a window that was read-only only because the other dsh had the team open,save()takes the free lock but adopts nothing, so the write replaced what the other host had left with this window's older copy — a friend's first line and a team exchange were lost that way — while every Agent write refused with the read-only error after the other host had closed. Both files now go throughrt.mutate(fn): it takes over, adopts what the other host left, and each record is re-resolved inside the callback, becauseadopt()replacesrt.statewhole and a reference captured before the call points at the discarded object.delivery.js:noteFriendLine(a friend's first line and the unread mark) and the team-exchange record are applied insidert.mutate.noteFriendLineanswers "first contact" as a promise now; its only caller already awaits in the same request.agents.js: add, adopt, archive and remove apply their change insidert.mutatewith the Agent re-resolved.beforeWrite()refreshes first, so a window whose lock was released takes over, and refuses while the lock is still someone else's — before any Session is created or archived.Red then green
core/test/mutate-writers.test.js, one two-host case per file in the shape ofcore/test/home-lock.test.js:233(#1032): the other host writesprefs, closes; thenprefs.themewas gone (expected: 'light');The Bot team in … is open in another dsh.On the unfixed sources only (both reverted, tests kept):
# tests 2 / # pass 0 / # fail 2. On the fix:2/2.Trade-offs
noteFriendLineis a promise now. Its one caller awaits it in the same request, so the delivery result is the same boolean.beforeWrite()re-checks after the refresh. Only the window whose lock file is gone takes over — the home-lock.test.js:184 flake: a write after the other host releases state.lock can still answer read-only #1027 rule, now applied to these writers too.What I ran
On the rebased tree
1c15f05f(base3f7e9515; core content identical to300cbbe8, where the full suite and the red proof below were run),node_modulessymlinked to the shared checkout,TZ=UTC,TMPDIRunder/data:test/mutate-writers.test.js+test/home-lock.test.js→# tests 15 / # pass 15 / # fail 0(the two new cases, and A save() that takes the state lock over logs nothing, so a stale window overwriting a newer state.json cannot be traced #1041's 13 still green).agents.jsanddelivery.jsreverted to300cbbe8→# tests 15 / # pass 13 / # fail 2, exactly the two new cases (expected: 'light'on the delivery one, the read-only refusal on the agents one).core/suite →# tests 1416 / # pass 1408 / # fail 8. Pristine300cbbe8(and2e54119fbefore it), same command →1414 / 1406 / 8with the same eight:empty diff passes(arch-docs needs git),composer-label/header-effects/read-page(need the built client bundle), the three A part handoff with an armed scheduled task never archives the earlier part: the archive races the un-awaited task move #896 part-archive cases, and theusage.sqlitefixture (no sqlite here). The diff adds two tests and no new failure.node scripts/ds-bot-patches.mjs check→ verbatim:node .github/scripts/changelog.mjs check→changelog: 14 fragment(s) in changelog.d/ are well formed.Not run:
npm run verifyend to end and the smoke test (dev/bench.sh smoke). This host has no git, no esbuild for the client bundle and no bench; the plugin suites are untouched by this diff.Notes
patches/ds-bot/0001-core-fixes.patchand0005-social-seams.patchare regenerated; the new test file is stored whole underpatches/ds-bot/files/test/, asgeneratewrites it.generateon this host (git 2.34.1) also rewrites the untouched patches with cosmetic diff-format changes (function context on hunk headers, indentation of unchanged context lines). I keptmain's copies of0002,0003and0008and committed only the two that carry this change;checkpasses with that set.docs/subsystems/core-host.mdnow records these writers as migrated instead of naming Move the remaining inline state writers onto rt.mutate() #1048 as the pending migration.changelog.d/1048-mutate-writers.fixed.mdis the user-facing half: the Agent writes no longer fail with the read-only error once the other window has closed.