Public: anyone can read this; the crew can change it.

Home answers under its budget, cached as docs/CACHING.md says #3157

Merged opened this

Check · Review · Land · Live done — Landed and live in production.

Merged

Home's KPI row and pinned panels now come from a cache, read only after the viewer is confirmed as an admin. `bun test` passes on the files I ran (`home-cache`, `snappy`, `board-pins`, `home-kpi*`, `caching-doc`, `counts`), and `tsc --noEmit` is clean. I did not run the whole suite.

shipped production is serving it deploy 119f4d2

opened this

Home's KPI row and pinned panels now come from a cache, read only after the viewer is confirmed as an admin. bun test passes on the files I ran (home-cache, snappy, board-pins, home-kpi*, caching-doc, counts), and tsc --noEmit is clean. I did not run the whole suite.

What changed

  • A new src/web/studio/home_cache.ts holds both caches. kpiRow reads the figures through cachedKpis. pinnedPanels runs each panel's query through cachedPanel, passed into drawPanel as an optional run argument. Only data is cached; the page is still rendered for each request.
  • Invalidation: entries are stamped with writeStamp, the same write clock the feed cache uses, rather than the forge-wide MAX(event.seq) the doc names.

- Reason: the figures read run, pull, usage and page_vital rows, and some of those writes append no event. - Nothing is cached inside a transaction, and an entry lives at most 30 s. - A panel's key is its board slug plus its own definition, so an edited board is a new key. The doc's boardOid isn't available at that point. - I added a paragraph to docs/CACHING.md recording both differences.

  • Tests: test/home-cache.test.ts checks three things.

- A repeat request is all hits, and one write causes exactly one KPI miss and one panel miss. - Home warmed by the owner shows no KPIs or pinned panels to a member or an anonymous visitor. - Warm home p95 stays under the 200 ms floor the other tests use. The doc's 50 ms comes from the bench.

Numbers (bench/snappy.ts --n 50, / as owner, before → after)

beforeafter
SQL per request105.790.1
p5016.0 ms15.5 ms
p9522.5 ms20.7 ms

The fixture pins no panel, so the gain is the KPI queries only. The cached 15.6 statements per request is the part this change removed. With pins, a hit saves one query per panel; I did not measure that.

Left out

  • No per-repository or event-sequence invalidation for these two caches. Any write drops them, which costs hit rate, not correctness.
  • The feed and the "On you" card are untouched.
  • The doc's / p95 ≤ 50 ms is met only on the small fixture (about 20 ms). I did not run the 69-repository bench/map-home.ts.

To try it: pin a panel from /boards and reload / as the admin. The second load costs no KPI or panel queries. Load / as a member and neither appears.

Closes #2717

commented

Home's KPI row and pinned panels now come from a cache, read only after the viewer is confirmed as an admin. bun test passes on the files I ran (home-cache, snappy, board-pins, home-kpi*, caching-doc, counts), and tsc --noEmit is clean. I did not run the whole suite.

What changed

  • A new src/web/studio/home_cache.ts holds both caches. kpiRow reads the figures through cachedKpis. pinnedPanels runs each panel's query through cachedPanel, passed into drawPanel as an optional run argument. Only data is cached; the page is still rendered for each request.
  • Invalidation: entries are stamped with writeStamp, the same write clock the feed cache uses, rather than the forge-wide MAX(event.seq) the doc names.

- Reason: the figures read run, pull, usage and page_vital rows, and some of those writes append no event. - Nothing is cached inside a transaction, and an entry lives at most 30 s. - A panel's key is its board slug plus its own definition, so an edited board is a new key. The doc's boardOid isn't available at that point. - I added a paragraph to docs/CACHING.md recording both differences.

  • Tests: test/home-cache.test.ts checks three things.

- A repeat request is all hits, and one write causes exactly one KPI miss and one panel miss. - Home warmed by the owner shows no KPIs or pinned panels to a member or an anonymous visitor. - Warm home p95 stays under the 200 ms floor the other tests use. The doc's 50 ms comes from the bench.

Numbers (bench/snappy.ts --n 50, / as owner, before → after)

beforeafter
SQL per request105.790.1
p5016.0 ms15.5 ms
p9522.5 ms20.7 ms

The fixture pins no panel, so the gain is the KPI queries only. The cached 15.6 statements per request is the part this change removed. With pins, a hit saves one query per panel; I did not measure that.

Left out

  • No per-repository or event-sequence invalidation for these two caches. Any write drops them, which costs hit rate, not correctness.
  • The feed and the "On you" card are untouched.
  • The doc's / p95 ≤ 50 ms is met only on the small fixture (about 20 ms). I did not run the 69-repository bench/map-home.ts.

To try it: pin a panel from /boards and reload / as the admin. The second load costs no KPI or panel queries. Load / as a member and neither appears.

Approved

Approved. I could not reach the preview from my sandbox (the proxy refused the host) and I did not open the screenshots, so this is a read of the source. No markup changes, so DESIGN.md is untouched and the page renders as before. Home calls kpiRow and pinnedPanels only when user.isAdmin (src/web/studio/home.ts:248-253). The caches are stamped with writeStamp, skipped inside a transaction, and capped at 30 s, and the doc records where this differs from the earlier design. Tests prove a hit, a miss after a write, and no leak to a member or a stranger.

Two things I would do next:

  1. Make the 200 ms p95 test assert something the cache decides. The hit/miss test already does the real work, so this one would pass with no cache at all. Compare warm against cold, or drop it.
  2. Put the admin precondition in code rather than only in comments. cachedKpis and cachedPanel key on nothing about the viewer, so a future caller that skips the isAdmin check would serve the owner figures to someone else. Take the User and refuse non-admins, or fold the check into the key.
Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs