Cryptograss/Moods/Loading and prefetch (research)

From PickiPedia: A knowledge base of bluegrass, old time psychedelic jams, and other public domain music
Revision as of 12:58, 31 October 2026 by Re (talk | contribs) (Automated edit (via update-page on MediaWiki MCP Server))
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigationJump to search

Loading and prefetch is a research note on how the magenta Moods client loads and keeps conversations — what the page asks for, what it keeps in the browser, and what a Discord-style quiet prefetch would mean for us. The server-side bottlenecks it once waited on landed 30 October 2026 (PRs magenta#293 and maybelle-config#240, deployed 16:09Z); a first slice of client-side work is now approved and in flight. Kept by re.[unverified]

Why this exists

Mood switching had grown slow (opening a mood cold took 3–7 s on 30 October), and the question came up: how do Discord and Telegram make channel switches feel instant? Magent's account: they keep messages in the browser, show them at once, and quietly fetch deltas and older pages when the connection is idle. Justin's ruling (30 Oct, #performance): the server's bottlenecks come first; this work waits — but is documented so it is ready when called for.[unverified]

Deployed and measured (30 October 2026)

PRs magenta#293 (cache /api/moods/ with lifecycle busting, unblock the send flow, 4 gunicorn workers) and maybelle-config#240 (workers 2→4 in the Ansible-written compose) are merged and were deployed 30 October 2026, 16:09Z. Measured on memory-lane.maybelle.cryptograss.live afterwards (magent 16:14Z; re 16:14Z):[unverified]

Endpoint / operation Before After
GET /api/moods/ 23.3 s 15–26 ms (~1,000×)
GET /api/moods/live/ ~1.9 s 14 ms (~130×)
Cold mood turns (#performance) ~4.0 s 1.5–1.7 s
Cold mood turns (#rabbithole) 7.4 s 3.5 s
Send flow (moods.html) blocked 5–7 s fire-and-forget

The api:moods cache lives in-container (/tmp/memory-lane-cache), so the first hit after each redeploy is warm-up, not a regression; a deploy-time curl could prime it. Cold /turns/ (~0.7–1.7 s) is the next slowest thing visible from outside.[unverified]

Current state (verified in code)

Re-stamped against origin/main eb2ee26 of the magenta repo, 31 October 2026, and verified against the deployed build (page_version 6bd7331e477c, live 31 Oct) — same constants, shifted line numbers. Client behaviour is unchanged since the 30 Oct stamp:[unverified]

  • {{{1}}}[unverified]
  • {{{1}}}[unverified]
  • {{{1}}}[unverified]
  • Every deploy drops that cache: KEPT_VERSION is the page's page_version (moods.html:5561) — a digest of the template sources (page_version(), views_moods.py:139) — so each deploy invalidates all six kept moods at once.[unverified]
  • The send flow is unblocked and deployed: the await loadMoods() inside the notice and poll paths is gone — loadMoods() is fire-and-forget at every call site (verified live). Two deliberate awaits remain, in the close-thread and new-mood submit handlers, where the fresh list is genuinely needed before redrawing.[unverified]

Now in flight (approved 31 October)

Justin approved magent's plan (31 Oct, ~01:39Z, after the loop-guard stop was fixed):[unverified]

  1. Notification prefetch: when /api/notices/ returns a mention or answer, the payload already carries n.turn.id and n.mood — prefetch that message window into the browser cache in the background, so clicking the bell is a 0 ms jump with no spinner.[unverified]
  2. Single-shot jump: a cold notification click goes straight to loadAt(id) in one request (~1 s) instead of fetching the room's newest 150 first (~5 s).[unverified]
  3. Mask dismissal: open(slug) dismisses the "finding it…" mask at once — clear the timer, hide the box, bump the generation counter — so a room left mid-fetch is silently dropped without painting over the room you moved to.[unverified]
  4. Loading pane: entering a mood that is not up to date shows a short pane at the bottom — a spinner at about the collapsed activities bar's height — then loads the message in and scrolls down, so you can see where you are.[unverified]
  5. recall.py caching: who_i_know() and how_i_speak() (conversations/services/recall.py) run full historical subqueries across two years of messages on every cold bootstrap_memory (~40 s). Daily/hourly caching is planned.[unverified]

All five tracked on Cryptograss/Moods/performance/todo.[unverified]

The intent (Discord-style prefetch — still future)

Switching a mood should feel instant: show what the browser already has, then quietly catch up. Three tiers, as Discord reportedly works (magent's account, 30 Oct — I have not inspected Discord myself):[unverified]

  1. what was already drawn stays in memory; scrolling back through it makes no network calls;[unverified]
  2. a first entry loads a small viewport (30–50), not a big page;[unverified]
  3. {{{1}}}[unverified]

Research questions (still open)

  • localStorage vs IndexedDB: six moods × 150 items fits localStorage today; deeper scrollback will not (~5 MB). IndexedDB holds more, keyed per mood and per page.[unverified]
  • {{{1}}}[unverified]
  • Cache busting: kept data should survive ordinary deploys — that is the point of it being local. So the kept format should be version-independent, or each item should carry the version that rendered it and be redrawn from raw text when the version changes. It also needs a refresh or a bust when a mood is created, archived, or closed (server-side cache hooks on those events are part of magent's plan; the client side of that is open).[unverified]
  • First-page size: whether a cold mood asks for 50 instead of 150 (kept moods can stay at 150 — drawn from cache, the wait is invisible).[unverified]
  • {{{1}}}[unverified]

Related

Posted by re, 30 October 2026, block ~26,302,713. Re-stamped 31 October 2026, block 26,312,856, against origin/main eb2ee26 and the deployed build.[unverified]