-
Notifications
You must be signed in to change notification settings - Fork 49
fix(amazonq): add cancel support to loading developer profiles #940
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,6 @@ | ||
import { | ||
AWSInitializationOptions, | ||
CancellationToken, | ||
Logging, | ||
LSPErrorCodes, | ||
ResponseError, | ||
|
@@ -22,6 +23,7 @@ export interface ListAllAvailableProfilesHandlerParams { | |
connectionType: SsoConnectionType | ||
logging: Logging | ||
endpoints?: Map<string, string> // override option for flexibility, we default to all (AWS_Q_ENDPOINTS) | ||
token: CancellationToken | ||
} | ||
|
||
export type ListAllAvailableProfilesHandler = ( | ||
|
@@ -33,7 +35,7 @@ const MAX_Q_DEVELOPER_PROFILES_PER_PAGE = 10 | |
|
||
export const getListAllAvailableProfilesHandler = | ||
(service: (region: string, endpoint: string) => CodeWhispererServiceToken): ListAllAvailableProfilesHandler => | ||
async ({ connectionType, logging, endpoints }) => { | ||
async ({ connectionType, logging, endpoints, token }) => { | ||
if (!connectionType || connectionType !== 'identityCenter') { | ||
logging.debug('Connection type is not set or not identityCenter - returning empty response.') | ||
return [] | ||
|
@@ -42,13 +44,21 @@ export const getListAllAvailableProfilesHandler = | |
let allProfiles: AmazonQDeveloperProfile[] = [] | ||
const qEndpoints = endpoints ?? AWS_Q_ENDPOINTS | ||
|
||
if (token.isCancellationRequested) { | ||
return [] | ||
} | ||
|
||
const result = await Promise.allSettled( | ||
Array.from(qEndpoints.entries(), ([region, endpoint]) => { | ||
const codeWhispererService = service(region, endpoint) | ||
return fetchProfilesFromRegion(codeWhispererService, region, logging) | ||
return fetchProfilesFromRegion(codeWhispererService, region, logging, token) | ||
}) | ||
) | ||
|
||
if (token.isCancellationRequested) { | ||
return [] | ||
} | ||
|
||
const fulfilledResults = result.filter(settledResult => settledResult.status === 'fulfilled') | ||
|
||
if (fulfilledResults.length === 0) { | ||
|
@@ -63,7 +73,8 @@ export const getListAllAvailableProfilesHandler = | |
async function fetchProfilesFromRegion( | ||
service: CodeWhispererServiceToken, | ||
region: string, | ||
logging: Logging | ||
logging: Logging, | ||
token: CancellationToken | ||
): Promise<AmazonQDeveloperProfile[]> { | ||
let allRegionalProfiles: AmazonQDeveloperProfile[] = [] | ||
let nextToken: string | undefined = undefined | ||
|
@@ -73,6 +84,10 @@ async function fetchProfilesFromRegion( | |
do { | ||
logging.debug(`Fetching profiles from region: ${region} (iteration: ${numberOfPages})`) | ||
|
||
if (token.isCancellationRequested) { | ||
return allRegionalProfiles | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: I think we could just return an empty list here, request might be cancelled after some profiles are already aggregated due to pagination and higher up we we will return an empty list after cancellation anyways There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. IMO this is a concern for the caller, whether the caller is within flare or from a client. In both places, the caller can decide what to do given that they have access to the token cancellation state. |
||
} | ||
|
||
const response = await service.listAvailableProfiles({ | ||
maxResults: MAX_Q_DEVELOPER_PROFILES_PER_PAGE, | ||
nextToken: nextToken, | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should cancel whole
onGetConfigurationFromServer
request and returnRequestCanceled
LSP Error from here to signal that client cancellation was handled by server correctly.https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#errorCodes
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed, we could for all switch cases here pass the token to a method e.g. handleTokenCancellation, which will throw a RequestCancelled error in case the request was cancelled.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure -- I'm going to refrain from adding it to the Q_CUSTOMIZATIONS_CONFIGURATION_SECTION case statement, because customizations code currently does not support tokens.