CS-11123 Phase 2: Bound-parallelize pre-warm walk#4800
Conversation
There was a problem hiding this comment.
Pull request overview
This PR implements CS-11123 Phase 2 by converting the module pre-warm step in IndexRunner from a serial loop into a bounded-parallel walk, aiming to reduce pre-warm wall-clock time on large invalidation sets while relying on existing in-flight deduplication in CachingDefinitionLookup.
Changes:
- Introduces
PRE_WARM_MAX_CONCURRENCY = 4to cap concurrentgetModuleCacheEntry()pre-warm work. - Replaces the serial pre-warm loop with a worker-queue pattern that processes module URLs in bounded parallel.
- Parallelizes resolving novel
.jsoninvalidations’adoptsFrom.modulereads viaPromise.all(...).
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
5abb6e3 to
f17b9a1
Compare
b144320 to
004c9b8
Compare
f17b9a1 to
e6a0a7f
Compare
004c9b8 to
bdd34dc
Compare
e6a0a7f to
209a065
Compare
Host Test Results 1 files ±0 1 suites ±0 2h 0m 18s ⏱️ + 12m 31s Results for commit d386c14. ± Comparison against earlier commit 209a065. Realm Server Test Results 1 files ±0 1 suites ±0 12m 26s ⏱️ +48s Results for commit d386c14. ± Comparison against earlier commit 209a065. |
Replace Phase 1's serial pre-warm loop with a bounded parallel walk: N workers (default PRE_WARM_MAX_CONCURRENCY = 4) pull from a shared queue of module URLs and call `getModuleCacheEntry` per slot. Concurrent same-URL callers continue to coalesce through `CachingDefinitionLookup`'s `#inFlight` map, so parallel pre-warm never duplicates a prerender. Also parallelize the upfront `adoptsFrom.module` disk reads for the novel `.json` invalidations — a wide invalidation set no longer pays N sequential file reads to resolve the pre-warm URL set. The cap of 4 matches the planned `INDEX_RUNNER_MAX_CONCURRENCY` from the sibling parallel-visit-loop work. The cap is on _admission_ here only — the prerender server's affinity-scoped tab queue still owns the real back-pressure against the pool; bounding here just keeps the websocket fan-out from spiking on large invalidation sets. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
209a065 to
d386c14
Compare
bdd34dc to
c85633d
Compare
|
closing this as the benchmark indicates that this worsens indexing time |
Summary
PRE_WARM_MAX_CONCURRENCY) pull from a shared queue of module URLs and callgetModuleCacheEntryper slot.adoptsFrom.modulesource reads (HTTP viareader.readFilein the worker process) for novel.jsoninvalidations — bounded by the same cap.CachingDefinitionLookup's#inFlightmap, so parallel pre-warm never duplicates a prerender.Bound rationale. The cap of 4 matches the planned
INDEX_RUNNER_MAX_CONCURRENCYfrom the sibling parallel-visit-loop work. The cap is on admission here only — the prerender server's affinity-scoped tab queue still owns the real back-pressure against the pool; bounding here just keeps the websocket fan-out from spiking on large invalidation sets.Built on top of Phase 1 (#4799). Base this PR's merge against
mainafter Phase 1 lands; until then it targets the Phase 1 branch.Test plan
/prudent-octopusreindex on top of this PR — total wall-clock drops vs Phase 1, no newinstanceErrors./ambitious/prianhareindex on top of this PR — still completes, total wall-clock drops vs Phase 1.🤖 Generated with Claude Code
Bench results (vite-dev rig, 2026-05-13)
Same-rig as the prior
mainbaseline (commit0119bac76d) and the Phase 1 numbers in #4799. Protocol:mise run kill-all→TRUNCATE job_reservations, jobs, job_progress→mise run dev-all→ boot drain → readiness-check mount → mount drain →time curl /_grafana-reindex.user/prudent-octopusmain 0119bac76duser/prudent-octopusc85633d237user/prudent-octopusd386c145a1user/ambitious-piranhamain 0119bac76duser/ambitious-piranhac85633d237user/ambitious-piranhad386c145a1Phase 2 does not deliver a measurable win
Octopus on Phase 2 is 45 s slower than Phase 1 (512 s vs 467 s, +9.6 %), not faster. Piranha is unchanged — still rejects at the 150 s prerender-server abort during the first cohort render.
The likeliest read: the prerender pool's affinity-scoped tab queue is already serializing module renders inside the per-realm affinity, so bounded-parallel admission at the indexer doesn't expand the effective concurrency — it just adds a small overhead (extra promise scheduling, more concurrent
#inFlightmap churn) that surfaces as the +45 s drift.Phase 2 pass-bar status
Recommendation: close this PR. Ship Phase 1 (serial pre-warm, with the
adoptsFromfix that resolves the octopusinstanceError) and Phase 3 (cacheOnlyDefinitionsunwind, conditional on piranha being addressable elsewhere) without the parallel walk.