Skip to content

⚡ Bolt: Reduce worker thread head-of-line blocking#383

Merged
AhmmedSamier merged 8 commits intomasterfrom
bolt/reduce-worker-hol-blocking-16728447728457543423
May 10, 2026
Merged

⚡ Bolt: Reduce worker thread head-of-line blocking#383
AhmmedSamier merged 8 commits intomasterfrom
bolt/reduce-worker-hol-blocking-16728447728457543423

Conversation

@AhmmedSamier
Copy link
Copy Markdown
Owner

@AhmmedSamier AhmmedSamier commented Apr 23, 2026

💡 What: Replaced a chunk-based Promise.all with a continuous concurrency pool (pLimit) in language-server/src/core/indexer-worker.ts.
🎯 Why: Previously, fast file parsing tasks had to wait for the slowest file in a fixed batch to complete before results were streamed back to the parent thread. This caused head-of-line blocking and unnecessary latency in the indexing pipeline.
📊 Impact: Improves parser throughput and provides smoother, faster streaming of code symbols back to the main thread by preventing fast tasks from stalling behind slow ones.
🔬 Measurement: Verify by executing the full test suite (cd language-server && bun test) and observing the indexing speed when reloading the VS Code workspace. All 75 tests pass correctly.


PR created automatically by Jules for task 16728447728457543423 started by @AhmmedSamier

Summary by CodeRabbit

  • Documentation

    • Added performance guidance recommending concurrency-limited batching to avoid head-of-line blocking and reduce tail latency.
  • Improvements

    • Reworked indexing to stream results in concurrency-limited batches, improving throughput and reducing latency when processing many files.

Co-authored-by: AhmmedSamier <17784876+AhmmedSamier@users.noreply.github.com>
@google-labs-jules
Copy link
Copy Markdown
Contributor

👋 Jules, reporting for duty! I'm here to lend a hand with this pull request.

When you start a review, I'll add a 👀 emoji to each comment to let you know I've read it. I'll focus on feedback directed at me and will do my best to stay out of conversations between you and other bots or reviewers to keep the noise down.

I'll push a commit with your requested changes shortly after. Please note there might be a delay between these steps, but rest assured I'm on the job!

For more direct control, you can switch me to Reactive Mode. When this mode is on, I will only act on comments where you specifically mention me with @jules. You can find this option in the Pull Request section of your global Jules UI settings. You can always switch back!

New to Jules? Learn more at jules.google/docs.


For security, I will only act on instructions from the user who triggered this task.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 23, 2026

Warning

Rate limit exceeded

@AhmmedSamier has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 39 minutes and 30 seconds before requesting another review.

You’ve run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 6cc5fe24-368b-441e-9d51-10922d69a95a

📥 Commits

Reviewing files that changed from the base of the PR and between 4216f29 and 15fa73a.

📒 Files selected for processing (2)
  • language-server/src/core/indexer-worker.ts
  • patch_last.js
📝 Walkthrough

Walkthrough

Replaces fixed-size Promise.all chunking with a pLimit-based concurrency-limited task queue in the indexer worker and adds guidance recommending this pattern; also adds a standalone script that documents a suspected CI/build failure caused by an incorrect import path.

Changes

Indexer worker refactor

Layer / File(s) Summary
Imports / Helpers
language-server/src/core/indexer-worker.ts
Adds pLimit import to enable concurrency-limited task scheduling.
Core Execution / Data Shape
language-server/src/core/indexer-worker.ts
Replaces chunked Promise.all producer/worker-loop with per-file tasks scheduled through pLimit(BATCH_SIZE) and a shared chunkItems accumulator.
Streaming Emission Logic
language-server/src/core/indexer-worker.ts
Emits result messages repeatedly when processedCount hits batch boundaries or on final completion; recomputes count and isPartial from processed-file counts.
Error Handling
language-server/src/core/indexer-worker.ts
Parse errors remain swallowed (no items produced).
Tests / Docs
(none changed)
No test or API surface changes in this diff.

Performance guidance

Layer / File(s) Summary
Documentation
.jules/bolt.md
Adds a 2026-04-23 guidance entry recommending replacing unconstrained Promise.all batching with a concurrency-limited task queue (e.g., pLimit) and streaming/pushing results to a shared collection with BATCH_SIZE flush boundaries.

CI / Investigation script

Layer / File(s) Summary
Diagnostic Script
patch_last.js
Adds a Node/Bun script that reads language-server/src/core/indexer-worker.ts and emits inline comments describing a suspected CI/integration failure caused by an incorrect import path for SearchableItem and the resulting broken dist/indexer-worker.js build.

Sequence Diagram(s)

sequenceDiagram
    actor Worker as Indexer Worker
    participant Queue as pLimit Queue<br/>(BATCH_SIZE)
    participant Parser as Parse Task
    participant Accum as Result Accumulator<br/>(chunkItems)
    participant Emitter as Result Emission

    Worker->>Queue: enqueue filePath task
    activate Queue
    Queue->>Parser: run up to BATCH_SIZE parse tasks concurrently
    activate Parser
    Parser-->>Accum: append parsed SearchableItem(s)
    deactivate Parser

    alt processedCount reaches BATCH_SIZE
        Accum->>Emitter: emit partial batch (count=BATCH_SIZE, isPartial=true)
    end

    alt All tasks complete
        Accum->>Emitter: emit final batch (count=remainder, isPartial=false)
    end
    deactivate Queue
Loading

Estimated Code Review Effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • AhmmedSamier/DeepLens#365: Similar replacement of Promise.all chunking with a pLimit concurrency-limited queue and streaming batch emission in indexer-worker.ts.
  • AhmmedSamier/DeepLens#378: Another closely related change to the same indexing worker logic to adopt pLimit-based streaming batches and matching guidance.
  • AhmmedSamier/DeepLens#373: Also modifies indexer-worker.ts to move from fixed Promise.all batching to pLimit-bounded streaming accumulation and partial result emissions.

Poem

I munched the tasks with nimble feet,
pLimit kept my hops discreet,
Batches flowed, no stubborn wait—
The indexer hummed, the files felt light. 🐇✨

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title directly addresses the main change: replacing Promise.all batching with a concurrency-limited queue to reduce worker thread head-of-line blocking, which is the core improvement across all modified files.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch bolt/reduce-worker-hol-blocking-16728447728457543423

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Co-authored-by: AhmmedSamier <17784876+AhmmedSamier@users.noreply.github.com>
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@language-server/src/core/indexer-worker.ts`:
- Around line 40-71: If filePaths is empty the Promise.all block never runs and
no terminal result is posted, leaking state.activeTasks; add an early check at
the top of the worker (in language-server/src/core/indexer-worker.ts) that if
filePaths.length === 0 immediately calls parentPort?.postMessage({ type:
'result', items: [], count: 0, isPartial: false }) and returns, so the worker
always emits a terminal result; this should be done before the Promise.all logic
that uses parser.parseFile, BATCH_SIZE, chunkItems and processedCount.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: a74c3287-48cc-4734-b27b-b8fdc27450a5

📥 Commits

Reviewing files that changed from the base of the PR and between 32a2408 and a354a15.

📒 Files selected for processing (2)
  • .jules/bolt.md
  • language-server/src/core/indexer-worker.ts

Comment thread language-server/src/core/indexer-worker.ts
google-labs-jules Bot and others added 4 commits April 23, 2026 01:43
Co-authored-by: AhmmedSamier <17784876+AhmmedSamier@users.noreply.github.com>
Co-authored-by: AhmmedSamier <17784876+AhmmedSamier@users.noreply.github.com>
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
patch_last.js (1)

1-109: ⚡ Quick win

Drop this one-off investigation script from the PR.

This file is an executable debugging transcript, not a test or a reusable build tool. Keeping it in the repo adds maintenance noise and stale context; if the narrative matters, it belongs in the PR description or an issue instead.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@patch_last.js` around lines 1 - 109, This file (patch_last.js) is a one-off
debugging transcript and should be removed from the PR: delete patch_last.js
from the repo/commit, ensure no other files import or reference it (search for
"patch_last.js" and the top-level variables like content or the console.log("I
see...") line), remove any executable bit or package.json script entries that
might invoke it, and if the investigation needs to be preserved move the
narrative into the PR description or an issue instead of keeping the script in
source control.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@language-server/src/core/indexer-worker.ts`:
- Around line 30-36: The code uses message.chunkSize to set BATCH_SIZE and pass
into pLimit without validating it, which allows 0, negatives, NaN or non-integer
values to break scheduling and the `% BATCH_SIZE` flush/count math; add a guard
when computing BATCH_SIZE to coerce/validate message.chunkSize into a positive
integer (e.g., parse/Math.floor and fallback to a safe default like 25) and
ensure it is >= 1 before calling pLimit and using the modulo-based flush logic
so pLimit(BATCH_SIZE) and the count/% BATCH_SIZE calculations never receive
invalid values; update the assignment where BATCH_SIZE is defined and use that
validated constant in pLimit and the flush/count code paths.

---

Nitpick comments:
In `@patch_last.js`:
- Around line 1-109: This file (patch_last.js) is a one-off debugging transcript
and should be removed from the PR: delete patch_last.js from the repo/commit,
ensure no other files import or reference it (search for "patch_last.js" and the
top-level variables like content or the console.log("I see...") line), remove
any executable bit or package.json script entries that might invoke it, and if
the investigation needs to be preserved move the narrative into the PR
description or an issue instead of keeping the script in source control.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 8f92e501-7ed6-4063-a73e-e20faaa73bc7

📥 Commits

Reviewing files that changed from the base of the PR and between a354a15 and 4216f29.

📒 Files selected for processing (2)
  • language-server/src/core/indexer-worker.ts
  • patch_last.js

Comment thread language-server/src/core/indexer-worker.ts
…l resolution

When filePaths is empty (warmup path), the worker now silently returns
after initializing the parser instead of posting a result message.

The previous behavior posted { type: 'result', isPartial: false } for
empty batches. This message was queued before runFileIndexingPool
attached its listeners, but delivered during the actual indexing run.
The handler then decremented activeTasks prematurely, causing the pool
to resolve before any symbols were parsed — leaving the search index
with only file items and no symbols/types.

Fixes: 4 failing vscode integration tests (EVERYTHING, TYPES, SYMBOLS,
ENDPOINTS scopes all returning 0 results).
@AhmmedSamier AhmmedSamier merged commit 27c3514 into master May 10, 2026
2 checks passed
@AhmmedSamier AhmmedSamier deleted the bolt/reduce-worker-hol-blocking-16728447728457543423 branch May 10, 2026 01:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant