Skip to content

Commit 187f27a

Browse files
authored
fix(amazonq): bring back timeout to local LSP call inline completion (#7780)
## Problem During the inline completion migration to Flare, the timeout handling of inline completion API was lost. It was there in earlier versions. The IDE -> Flare call is a local network call that should have a timeout. ## Solution Add the inline completion call with timeout back. See https://github.com/aws/aws-toolkit-vscode/blob/amazonq/v1.74.0/packages/core/src/codewhisperer/util/commonUtil.ts#L21 --- - Treat all work as PUBLIC. Private `feature/x` branches will not be squash-merged at release time. - Your code changes must meet the guidelines in [CONTRIBUTING.md](https://github.com/aws/aws-toolkit-vscode/blob/master/CONTRIBUTING.md#guidelines). - License: I confirm that my contribution is made under the terms of the Apache 2.0 license.
1 parent 9e7b13c commit 187f27a

File tree

2 files changed

+43
-11
lines changed

2 files changed

+43
-11
lines changed

packages/amazonq/src/app/inline/recommendationService.ts

Lines changed: 28 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,16 @@ import {
1212
import { CancellationToken, InlineCompletionContext, Position, TextDocument } from 'vscode'
1313
import { LanguageClient } from 'vscode-languageclient'
1414
import { SessionManager } from './sessionManager'
15-
import { AuthUtil, CodeWhispererStatusBarManager, vsCodeState } from 'aws-core-vscode/codewhisperer'
15+
import {
16+
AuthUtil,
17+
CodeWhispererConstants,
18+
CodeWhispererStatusBarManager,
19+
vsCodeState,
20+
} from 'aws-core-vscode/codewhisperer'
1621
import { TelemetryHelper } from './telemetryHelper'
1722
import { ICursorUpdateRecorder } from './cursorUpdateManager'
1823
import { getLogger } from 'aws-core-vscode/shared'
24+
import { asyncCallWithTimeout } from '../../util/timeoutUtil'
1925

2026
export interface GetAllRecommendationsOptions {
2127
emitTelemetry?: boolean
@@ -35,6 +41,23 @@ export class RecommendationService {
3541
this.cursorUpdateRecorder = recorder
3642
}
3743

44+
async getRecommendationsWithTimeout(
45+
languageClient: LanguageClient,
46+
request: InlineCompletionWithReferencesParams,
47+
token: CancellationToken
48+
) {
49+
const resultPromise: Promise<InlineCompletionListWithReferences> = languageClient.sendRequest(
50+
inlineCompletionWithReferencesRequestType.method,
51+
request,
52+
token
53+
)
54+
return await asyncCallWithTimeout<InlineCompletionListWithReferences>(
55+
resultPromise,
56+
`${inlineCompletionWithReferencesRequestType.method} time out`,
57+
CodeWhispererConstants.promiseTimeoutLimit * 1000
58+
)
59+
}
60+
3861
async getAllRecommendations(
3962
languageClient: LanguageClient,
4063
document: TextDocument,
@@ -93,11 +116,9 @@ export class RecommendationService {
93116
},
94117
})
95118
const t0 = performance.now()
96-
const result: InlineCompletionListWithReferences = await languageClient.sendRequest(
97-
inlineCompletionWithReferencesRequestType.method,
98-
request,
99-
token
100-
)
119+
120+
const result = await this.getRecommendationsWithTimeout(languageClient, request, token)
121+
101122
getLogger().info('Received inline completion response from LSP: %O', {
102123
sessionId: result.sessionId,
103124
latency: performance.now() - t0,
@@ -181,11 +202,7 @@ export class RecommendationService {
181202
while (nextToken) {
182203
const request = { ...initialRequest, partialResultToken: nextToken }
183204

184-
const result: InlineCompletionListWithReferences = await languageClient.sendRequest(
185-
inlineCompletionWithReferencesRequestType.method,
186-
request,
187-
token
188-
)
205+
const result = await this.getRecommendationsWithTimeout(languageClient, request, token)
189206
// when pagination is in progress, but user has already accepted or rejected an inline completion
190207
// then stop pagination
191208
if (this.sessionManager.getActiveSession() === undefined || vsCodeState.isCodeWhispererEditing) {
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
/*!
2+
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
export function asyncCallWithTimeout<T>(asyncPromise: Promise<T>, message: string, timeLimit: number): Promise<T> {
7+
let timeoutHandle: NodeJS.Timeout
8+
const timeoutPromise = new Promise((_resolve, reject) => {
9+
timeoutHandle = setTimeout(() => reject(new Error(message)), timeLimit)
10+
})
11+
return Promise.race([asyncPromise, timeoutPromise]).then((result) => {
12+
clearTimeout(timeoutHandle)
13+
return result as T
14+
})
15+
}

0 commit comments

Comments
 (0)