diff --git a/docs/async_refactor.md b/docs/async_refactor.md index fca6e27..b54d54b 100644 --- a/docs/async_refactor.md +++ b/docs/async_refactor.md @@ -1,6 +1,6 @@ # Async refactor — findings, priorities, and how to keep it that way -**Status: P0 and the loop-lag probe are done (2026-08-11). P1–P3 outstanding.** To be implemented once the in-flight chart +**Status: P0, P1 and the loop-lag probe are done (2026-08-11). P2 and P3 outstanding.** To be implemented once the in-flight chart work has landed. Everything below is from reading the code on 2026-08-11 and measuring the running app; each finding names the path it was found on. @@ -72,7 +72,29 @@ intervening. Today that passes by luck. --- -## P1 — Level rebuilding is CPU-bound on the loop (latency) +## P1 — Level rebuilding is CPU-bound on the loop (latency) — DONE + +Measured on the dev stack, Yahoo source: + +| | before | after | +|---|---|---| +| port accepting connections | 121s | 4s | +| worst loop lag | 19,545ms | 526ms | +| steady-state lag | — | 0.2–0.6ms | + +Two changes did it. Seeding now accumulates into the store and derives price, +ATR and the level set **once** at the end (`settle_after_seed`) instead of +rebuilding per replayed bar. And `request_rebuild` coalesces rebuilds to at most +one per 250ms with a guaranteed trailing pass, which matters because Yahoo's +first poll emits a whole day of minutes in one burst — that burst, not the seed, +was most of the remaining 20 seconds. Bar counts, all five daily MAs, prior-day +levels and VWAP are unchanged; 125 python tests and 31 e2e tests pass. + +Still open from the original list: incremental moving averages, and diffing +levels by fingerprint rather than by re-serialising every point. Neither is +needed while lag sits under a second. + +### Original analysis `rebuild_levels()` recomputes all five daily moving averages and re-serialises their points to diff them, on every closed bar. Measured consequence: the seed