diff options
| author | Christophe Besson <cbesson@gmail.com> | 2026-09-02 17:31:50 +0200 |
|---|---|---|
| committer | Christophe Besson <cbesson@gmail.com> | 2026-09-02 17:31:50 +0200 |
| commit | 7b25f1c09ba1b8692988d9616f3c33c97af9f3ca (patch) | |
| tree | 1a7d346ea6a3847269df4aeff3c6b41d515b5d7b /docs/refactoring-search.md | |
| parent | 10f8266e7152d7dc38dbfe2449327829bf020ad1 (diff) | |
| download | meshbay-7b25f1c09ba1b8692988d9616f3c33c97af9f3ca.tar.gz | |
fix(hub): stop the maintenance loop racing the tests, and pin _ASSETS
Two defects found while closing out the Search merge, neither of them in
that feature.
The maintenance loop. create_app's lifespan starts cleanup_loop as an
asyncio task, so every test — each entering that lifespan — ran a purge
pass concurrently with its own requests. On SQLite :memory: that is not
merely noisy: the engine uses a StaticPool, one connection for the whole
process, so the request's session and the cleanup task's session
interleave transactions on the same connection. A registration could
commit and then be invisible to the login three lines later, surfacing
as 401 Invalid credentials for an account created moments before, in
roughly one run of test_node_ws_auth.py in four.
The purge itself is not at fault and this is not a production condition.
A passive SQL listener caught the DELETE removing 0 rows, and the INSERT
carrying status='active' — so neither the pending-account mechanism nor
the purge filter is involved, and PostgreSQL gives every session its own
connection. What the fixture removes is the second user of the shared
one. 60 runs of the previously flaky file, 0 failures; reproductions
before the fix landed on attempts 4, 6, 13 and 29 of separate loops, so
a clean run of 60 has about a 1% chance of being luck.
_ASSETS. source-merge.js shipped missing from webapp._ASSETS, the
cache-busting hash's input list — exactly the silent failure docs/apps.md
§4 step 5 warns about: the file changes, the asset URL does not, and a
browser holding the old page keeps the old copy. Harmless this time only
because search-page.js changed in the same commit and is listed, which is
the worst way for it to go unnoticed. Found by re-reading that checklist
for the doc pass, not by any test — so there is a test now, holding
_ASSETS to every .js in static/ (sw.js excepted, unversioned on purpose).
It was the only one missing.
Phase 9 of docs/refactoring-search.md also lands here: mediacenter.md
§10.6, musicbay.md §9b, photos.md §10b, apps.md §2b and step 5.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AbwJDbNTkiRUh7HTWEoyss
Diffstat (limited to 'docs/refactoring-search.md')
| -rw-r--r-- | docs/refactoring-search.md | 10 |
1 files changed, 8 insertions, 2 deletions
diff --git a/docs/refactoring-search.md b/docs/refactoring-search.md index 2210397..d39bd36 100644 --- a/docs/refactoring-search.md +++ b/docs/refactoring-search.md @@ -1,6 +1,7 @@ # Refactor: one file, one entry — merging duplicate sources in the Search view -> Status: **phases 1–8 built** (2026-09-02), 9 (the doc pass) outstanding. +> Status: **complete** (2026-09-02) — all nine phases landed. This stays as +> the decision record. > Branch `feat/search-source-merge`. Videos, Music and Photos are merged, > failover is in, and a card with several sources says `N sources` instead of a > group name. Confirmed live for Videos on 2026-09-02: one card per film, @@ -335,6 +336,11 @@ be easy to ship and hard to notice. override lands on whichever node was picked. 7. **`cacheGroupIndex`.** The IndexedDB cache is per group and stores raw index entries. Merged entries must never be written to it. +8. **`webapp.py`'s `_ASSETS`.** A new static file missing from it changes + without moving the asset URL, so a browser that cached the page keeps the + old copy — and nothing errors. `source-merge.js` shipped missing from it; + caught afterwards, and `test_every_static_script_participates_in_the_fingerprint` + now holds the list to every `.js` in `static/` so the next one cannot. --- @@ -352,7 +358,7 @@ Each phase is independently testable and leaves the tree working. | 6 ✅ | Same for Photos | `search-page.js` | | 7 ✅ | `downGroups` and failover | `search-page.js` | | 8 ✅ | `SourceTag` at the four display sites; `search.n_sources` in ten catalogues | `group-name.js`, `video-app.js`, `music-app.js`, `photos-app.js`, `locales/*.js` | -| 9 | Docs: `mediacenter.md` §10, `musicbay.md`, `photos.md`, `apps.md` if the props contract moves | `docs/` | +| 9 ✅ | Docs: `mediacenter.md` §10.6, `musicbay.md` §9b, `photos.md` §10b, `apps.md` §2b + checklist step 5 | `docs/` | Phase 4 alone was enough to confirm the reported bug is gone; phases 5–8 are the same mechanism applied outward. |