Skip to content

fix: eliminate repeated JSONL delta reconstruction that starves extension host#565

Open
tianzheng-zhou wants to merge 2 commits intorajbos:mainfrom
tianzheng-zhou:fix/jsonl-reconstruction-event-loop-starvation
Open

fix: eliminate repeated JSONL delta reconstruction that starves extension host#565
tianzheng-zhou wants to merge 2 commits intorajbos:mainfrom
tianzheng-zhou:fix/jsonl-reconstruction-event-loop-starvation

Conversation

@tianzheng-zhou
Copy link
Copy Markdown

@tianzheng-zhou tianzheng-zhou commented Apr 9, 2026

Fixes #566

Root cause: the extension host's single-threaded event loop was blocked by repeated synchronous split+JSON.parse+applyDelta loops on the same large delta-based JSONL files across multiple analysis helpers, triggering the VS Code unresponsive watchdog and crash-restart loop.

Three fixes:

  1. usageAnalysis.ts: the delta-based JSONL early-return branch in analyzeSessionUsage now computes model switching inline from the already-reconstructed sessionState instead of calling calculateModelSwitching (which re-read the file and called getModelUsageFromSession for yet another re-read). The non-delta JSONL and regular JSON paths now pass preloadedContent through to calculateModelSwitching and trackEnhancedMetrics to avoid re-reads.

  2. extension.ts: removed the hidden pre-warm of calculateUsageAnalysisStats that ran even when the analysis panel was not open. This triggered workspace customization scans and JSONL processing on every 5-minute timer tick, amplifying the event-loop starvation on startup.

  3. extension.ts: replaced hand-rolled synchronous applyDelta loops in the session details and log viewer paths with reconstructJsonlStateAsync, a new helper in tokenEstimation.ts that yields to the event loop every 500 lines to prevent blocking.

…sion host

Root cause: the extension host's single-threaded event loop was blocked by
repeated synchronous split+JSON.parse+applyDelta loops on the same large
delta-based JSONL files across multiple analysis helpers, triggering the
VS Code unresponsive watchdog and crash-restart loop.

Three fixes:

1. usageAnalysis.ts: the delta-based JSONL early-return branch in
   analyzeSessionUsage now computes model switching inline from the
   already-reconstructed sessionState instead of calling
   calculateModelSwitching (which re-read the file and called
   getModelUsageFromSession for yet another re-read). The non-delta
   JSONL and regular JSON paths now pass preloadedContent through to
   calculateModelSwitching and trackEnhancedMetrics to avoid re-reads.

2. extension.ts: removed the hidden pre-warm of calculateUsageAnalysisStats
   that ran even when the analysis panel was not open. This triggered
   workspace customization scans and JSONL processing on every 5-minute
   timer tick, amplifying the event-loop starvation on startup.

3. extension.ts: replaced hand-rolled synchronous applyDelta loops in the
   session details and log viewer paths with reconstructJsonlStateAsync,
   a new helper in tokenEstimation.ts that yields to the event loop every
   500 lines to prevent blocking.
@tianzheng-zhou tianzheng-zhou changed the title fix: eliminate repeated JSONL delta reconstruction that starves exten… fix: eliminate repeated JSONL delta reconstruction that starves extension host Apr 9, 2026
@rajbos rajbos requested a review from Copilot April 9, 2026 21:07
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR addresses extension-host unresponsiveness/crash loops caused by repeatedly re-reading and synchronously reconstructing large delta-based JSONL Copilot session logs, especially during periodic background updates and usage analysis.

Changes:

  • Avoid redundant JSONL file reads/re-parses in usage analysis by passing preloaded content through and computing delta-based model switching from already-reconstructed state.
  • Stop pre-warming usage analysis stats when the analysis panel isn’t open (prevents heavy background work every timer tick).
  • Introduce an async delta-state reconstruction helper that periodically yields to the event loop, and use it in session details/log viewer paths.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.

File Description
vscode-extension/src/usageAnalysis.ts Thread preloaded content through model switching/enhanced metrics and avoid re-reading delta JSONL by computing switching from reconstructed state.
vscode-extension/src/tokenEstimation.ts Add reconstructJsonlStateAsync() to reconstruct delta-based JSONL while yielding to the event loop.
vscode-extension/src/extension.ts Remove hidden usage analysis pre-warm; use async JSONL reconstruction in session details/log viewer to reduce event-loop starvation.

Comment on lines +1286 to +1296
const models: string[] = [];
for (const req of requests) {
if (!req || !req.requestId) { continue; }
let reqModel = 'gpt-4o';
if (req.modelId) {
reqModel = req.modelId.replace(/^copilot\//, '');
} else if (req.result?.metadata?.modelId) {
reqModel = req.result.metadata.modelId.replace(/^copilot\//, '');
} else if (req.result?.details) {
reqModel = getModelFromRequest(req, deps.modelPricing);
}
Copy link

Copilot AI Apr 9, 2026

Choose a reason for hiding this comment

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

In the delta-based JSONL branch, the inline model-switching logic defaults to 'gpt-4o' when a request lacks modelId/result.metadata.modelId. Reconstructed requests can legitimately omit modelId (the logviewer path already falls back to sessionState.inputState.selectedModel), so this can misattribute models and under/over-count switches/tiers for sessions that used a different selected model. Consider deriving a defaultModel from sessionState.inputState?.selectedModel (identifier/metadata.id) and using it as the fallback before hard-coding a default.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

@copilot apply changes based on this feedback

@rajbos rajbos enabled auto-merge (squash) April 9, 2026 21:10
Copy link
Copy Markdown
Owner

@rajbos rajbos left a comment

Choose a reason for hiding this comment

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

LGTM, works on debugging.

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.

[BUG][vscode] Extension host crashes and enters infinite restart loop after upgrading to v0.0.25

3 participants