Parallelize the cache-warming loop in `cache-warming.service.ts` — warmers run strictly sequentially
@syntaxsuuvam-spec is already working on this.
Since Oct 11, 2026.
Assessment
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Newbie friendliness
- 72/100
- Issue type
- Refactor
- Clarity
- Clearly specified
- Activity status
- Active
- Tech stack
- nodejs, typescript
- Domain
- backend, performance
Research direction
Start with the sequential for loop over this.warmers in src/common/cache/cache-warming.service.ts (around lines 64-68) and the per-warmer error handling after it. Check singleflight in src/common/cache/cache.service.ts (around line 285) to confirm it deduplicates concurrent identical work. Done means warmers run concurrently, a failing warmer does not stop the others, totalEntries and successCount stay correct, a new partial-failure test passes in src/common/cache/cache.spec.ts, and before/after timings are recorded.
Written by the indexing model from the issue text.
Description
Problem
src/common/cache/cache-warming.service.ts:64-68 runs cache warmers one after another:
for (const warmer of this.warmers) {
try {
const count = await warmer.execute(this.cache);
totalEntries += count;
successCount++;
Each await blocks the loop, so total warm time is the sum of every warmer's duration rather than the maximum. If there are several warmers and each touches the database, startup and periodic warming pay that serial cost every cycle.
Why it matters
Warm-up is on the critical path of cold starts and of any periodic re-warm. src/common/cache/ already has the pieces to do this properly — and this is a small, well-contained change, which makes it a good first performance issue.
Be aware of one nuance before parallelising: src/common/cache/cache.service.ts has a singleflight method (line 285) that collapses concurrent identical work, so if two warmers populate the same key, parallel execution is safe and even beneficial. Confirm that is how it behaves.
Suggested Direction
- Run the warmers concurrently with
Promise.all, collecting results:const results = await Promise.allSettled( this.warmers.map((w) => w.execute(this.cache)), ); - Use
allSettled, notall. The current code catches per-warmer errors and continues (lines 73+), recordingsuccessCountseparately.Promise.allwould reject on the first failure and abandon the rest — a behaviour regression.allSettledpreserves the existing per-warmer isolation. - Keep the per-warmer logging that already exists, so a failure is still attributable to a named warmer.
- Consider a concurrency bound. If many warmers are registered and each is expensive, unbounded parallelism could overload the database on startup.
Promise.allon a handful of warmers is fine; if the count can grow large, add a small concurrency limit.
Constraints
- Preserve the existing error-isolation behaviour: one failing warmer must not prevent the others.
totalEntriesandsuccessCountmust still be reported accurately.- If two warmers write the same key, verify
singleflightprevents duplicated work rather than relying on serial ordering. - Tests already exist at
src/common/cache/cache.spec.ts(590 lines) — make sure the warming tests still pass, and add one asserting that a failing warmer does not prevent the others.
Acceptance Criteria
- Warmers execute concurrently rather than sequentially.
- A failing warmer does not prevent other warmers from completing.
-
totalEntriesandsuccessCountremain accurate. - A test covers the partial-failure case.
-
src/common/cache/cache.spec.tsstill passes. - The change is described with a before/after duration measurement.
- Dominant language
- TypeScript
- Stars
- 7
- Forks
- 55
- Avg merge
- 1d 17h
- Merged PRs (30d)
- 5
Getting set up
- Ships a Dockerfile or Docker Compose file
- Has a pull request template
- Read the contributing guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from SourceXXL/alian_structure-api
-
good first issue help wanted security
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
SourceXXL/alian_structure-api#266 ·
-
documentation help wanted intermediate refactor
Difficulty 2/5 1-3 hours Newbie friendliness 70/100
SourceXXL/alian_structure-api#215 ·
-
good first issue refactor tooling
Difficulty 2/5 1-3 hours Newbie friendliness 80/100
SourceXXL/alian_structure-api#199 ·
-
help wanted intermediate refactor
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
SourceXXL/alian_structure-api#196 ·
-
documentation good first issue
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
SourceXXL/alian_structure-api#175 ·
All issues in SourceXXL/alian_structure-api
Similar issues
-
area:ui effort:S enhancement priority:P2
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 74/100
QuantumNous/new-api#7839 ·
Maintainers usually reply within 1 day
-
good first issue maintenance
Difficulty 2/5 1-3 hours Newbie friendliness 62/100
dark-princezz/stellar-hooks#1010 ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
interledger/rhyza#352 ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 70/100
Maintainers usually reply within 1 day