Fix: NES debounce and language context fetch do not honor cancellation token#4384
Merged
ulugbekna merged 2 commits intomicrosoft:mainfrom Mar 17, 2026
Merged
Fix: NES debounce and language context fetch do not honor cancellation token#4384ulugbekna merged 2 commits intomicrosoft:mainfrom
ulugbekna merged 2 commits intomicrosoft:mainfrom
Conversation
|
LGTM! |
Contributor
There was a problem hiding this comment.
Pull request overview
This PR fixes cancellation handling in the Next Edit Suggestions (NES) pipeline within XtabProvider, so cancelled requests don’t continue to block during debounce or language-context collection—reducing queued-up latency for subsequent requests.
Changes:
- Wire the request
CancellationTokeninto the debounce wait so it resolves immediately on cancellation. - Wrap the language context timeout wait with cancellation, so cancellation stops waiting for the remaining time budget.
- Add unit tests covering cancellation during debounce and pre-cancelled requests.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
src/extension/xtab/node/xtabProvider.ts |
Makes debounce and language-context waiting honor cancellation via raceCancellation. |
src/extension/xtab/test/node/xtabProvider.spec.ts |
Adds unit tests asserting cancellation exits early and avoids issuing the LLM fetch. |
Comments suppressed due to low confidence (1)
src/extension/xtab/node/xtabProvider.ts:556
getLanguageContextnow stops waiting on cancellation viaraceCancellation(...), but it still proceeds to computelangCtxOnTimeoutand runisSnippetIgnoredchecks afterward. That additional async work can still delay promise resolution even after cancellation, undermining the goal of exiting immediately. Consider short-circuiting right after the await whencancellationToken.isCancellationRequested(e.g., returnundefined/ skip on-timeout processing when cancelled).
const start = Date.now();
await raceCancellation(raceTimeout(getContextPromise(), debounceTime), cancellationToken);
const end = Date.now();
const langCtxOnTimeout = this.langCtxService.getContextItemsOnTimeout(textDoc, ctxRequest);
for (const item of langCtxOnTimeout) {
You can also share your feedback on Copilot code review. Take the survey.
chrmarti
approved these changes
Mar 16, 2026
benibenj
approved these changes
Mar 16, 2026
Contributor
Author
Contributor
Author
|
@ulugbekna, @benibenj or anyone else, this PR was removed from merge queue due to test error "Failed to download and unzip VS Code insiders-unreleased". Any recommendations on how to resolve it? |
ulugbekna
pushed a commit
that referenced
this pull request
Mar 17, 2026
ulugbekna
pushed a commit
that referenced
this pull request
Mar 17, 2026
ulugbekna
pushed a commit
that referenced
this pull request
Mar 17, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #4383
Problem
When Visual Studio cancels a Next Edit Suggestions (NES) request (e.g. because the user moved the cursor or a new request superseded the old one), the cancellation was effectively a no-op for two critical phases of the request pipeline in \XtabProvider:
Impact on request queuing
Because cancelled requests would not yield until the debounce (and optionally the language context timeout) fully elapsed, subsequent NES requests accumulated behind them. Each queued request inherited an artificially inflated wait time, causing a visible multi-hundred-millisecond delay before later requests could start their own debounce or LLM fetch. In scenarios where VS fires rapid NES requests (e.g. caret moves after Tab acceptance) this manifested as a stall: the cancelled request's debounce blocked the pipeline, making healthy follow-on requests appear delayed or entirely unresponsive.
Fix
The debounce now resolves immediately when the cancellation token fires, instead of always waiting the full configured window.
Behavior Change
Testing
New unit tests (\src/extension/xtab/test/node/xtabProvider.spec.ts)
Two tests were added to the \XtabProvider integration > debounce behavior\ suite:
*\cancellation during debounce exits early with GotCancelled before LLM fetch*
*\pre-cancelled token resolves without waiting for debounce*
Existing test coverage
Manual validation
In VS, cancel rapid successive NES requests (cursor moves, new edits) and verify via ETW / LSP logs that follow-on \NES.GetNextEdit.Start\ events are no longer delayed by the predecessor's debounce window.