0.9.21 user-observed: the desktop app is much faster than 0.9.20, but cycling Today > 7D > 30D > 6M > back to 7D refetches 7D and recomputes its aggregation (~1.5-6s per period on a ~21k-file corpus), because (a) the renderer's per-period payload cache has a 30s TTL, and (b) the resident serve child caches the parse, not the per-period aggregation.
Two-part proposal:
1. Stale-while-revalidate in the app renderer (small, big UX win). On period switch, render the last payload for that period immediately (marked via the existing add-only stale field semantics, #1100) and refresh behind it, exactly like the menubar's show-then-refresh pattern. No new wire format.
2. Period-result cache in the serve child (bigger). Cache the derived menubar-json payload per (period, provider, scope, filters) keyed on the session-cache fingerprint, so an unchanged corpus serves a repeat period in milliseconds, across ALL serve clients (app, menubar, web). Invalidation = the fingerprint/watch machinery serve already runs. Disk persistence of these results (surviving restarts) is the natural extension and is exactly the territory of #999 (dgabehar's disk-persisted snapshot PR, currently held) — coordinate rather than duplicate: #999 persists the snapshot across processes; this issue wants the in-memory result keyed per period first.
The parse-level cache is already shared cross-surface (why all surfaces agree on numbers); this issue is about sharing the finished answers too.
Measured today (0.9.21, real corpus): serve child warm, per-period first ask 1.4-6.4s, repeat ask within renderer TTL instant, repeat after TTL full recompute.
0.9.21 user-observed: the desktop app is much faster than 0.9.20, but cycling Today > 7D > 30D > 6M > back to 7D refetches 7D and recomputes its aggregation (~1.5-6s per period on a ~21k-file corpus), because (a) the renderer's per-period payload cache has a 30s TTL, and (b) the resident serve child caches the parse, not the per-period aggregation.
Two-part proposal:
1. Stale-while-revalidate in the app renderer (small, big UX win). On period switch, render the last payload for that period immediately (marked via the existing add-only
stalefield semantics, #1100) and refresh behind it, exactly like the menubar's show-then-refresh pattern. No new wire format.2. Period-result cache in the serve child (bigger). Cache the derived menubar-json payload per (period, provider, scope, filters) keyed on the session-cache fingerprint, so an unchanged corpus serves a repeat period in milliseconds, across ALL serve clients (app, menubar, web). Invalidation = the fingerprint/watch machinery serve already runs. Disk persistence of these results (surviving restarts) is the natural extension and is exactly the territory of #999 (dgabehar's disk-persisted snapshot PR, currently held) — coordinate rather than duplicate: #999 persists the snapshot across processes; this issue wants the in-memory result keyed per period first.
The parse-level cache is already shared cross-surface (why all surfaces agree on numbers); this issue is about sharing the finished answers too.
Measured today (0.9.21, real corpus): serve child warm, per-period first ask 1.4-6.4s, repeat ask within renderer TTL instant, repeat after TTL full recompute.