Skip to content

Commit 4150566

Browse files
committed
fix to remove waitUntilCancellation
1 parent 4b4fff8 commit 4150566

File tree

3 files changed

+15
-130
lines changed

3 files changed

+15
-130
lines changed

packages/core/src/codewhispererChat/controllers/chat/controller.ts

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1619,15 +1619,7 @@ export class ChatController {
16191619
return
16201620
}
16211621

1622-
await this.messenger.sendAIResponse(
1623-
response,
1624-
session,
1625-
tabID,
1626-
triggerID,
1627-
triggerPayload,
1628-
chatHistory,
1629-
this.cancelTokenSource.token
1630-
)
1622+
await this.messenger.sendAIResponse(response, session, tabID, triggerID, triggerPayload, chatHistory)
16311623
} catch (e: any) {
16321624
this.telemetryHelper.recordMessageResponseError(triggerPayload, tabID, getHttpStatusCode(e) ?? 0)
16331625
// clears session, record telemetry before this call

packages/core/src/codewhispererChat/controllers/chat/messenger/messenger.ts

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
* SPDX-License-Identifier: Apache-2.0
44
*/
55

6-
import * as vscode from 'vscode'
76
import {
87
AppToWebViewMessageDispatcher,
98
AuthNeededException,
@@ -69,7 +68,7 @@ import { AsyncEventProgressMessage } from '../../../../amazonq/commons/connector
6968
import { localize } from '../../../../shared/utilities/vsCodeUtils'
7069
import { getDiffLinesFromChanges } from '../../../../shared/utilities/diffUtils'
7170
import { ConversationTracker } from '../../../storages/conversationTracker'
72-
import { waitUntilWithCancellation } from '../../../../shared/utilities/timeoutUtils'
71+
import { waitTimeout, Timeout } from '../../../../shared/utilities/timeoutUtils'
7372

7473
export type StaticTextResponseType = 'quick-action-help' | 'onboarding-help' | 'transform' | 'help'
7574

@@ -198,8 +197,7 @@ export class Messenger {
198197
tabID: string,
199198
triggerID: string,
200199
triggerPayload: TriggerPayload,
201-
chatHistoryManager: ChatHistoryManager,
202-
cancelToken: vscode.CancellationToken
200+
chatHistoryManager: ChatHistoryManager
203201
) {
204202
let message = ''
205203
const messageID = response.$metadata.requestId ?? ''
@@ -237,12 +235,15 @@ export class Messenger {
237235
})
238236

239237
const eventCounts = new Map<string, number>()
240-
await waitUntilWithCancellation(
238+
const timeout = new Timeout(600000) // 10 minutes timeout
239+
240+
await waitTimeout(
241241
async () => {
242242
for await (const chatEvent of response.message!) {
243-
if (cancelToken.isCancellationRequested) {
243+
if (this.isTriggerCancelled(triggerID)) {
244244
return
245245
}
246+
246247
for (const key of keys(chatEvent)) {
247248
if ((chatEvent[key] as any) !== undefined) {
248249
eventCounts.set(key, (eventCounts.get(key) ?? 0) + 1)
@@ -446,11 +447,14 @@ export class Messenger {
446447
}
447448
return true
448449
},
450+
timeout,
449451
{
450-
timeout: 600000,
451-
interval: 500,
452-
truthy: true,
453-
cancellationToken: conversationTracker.getTokenForTrigger(triggerID) ?? session.tokenSource.token,
452+
onCancel: () => {
453+
if (this.isTriggerCancelled(triggerID)) {
454+
return true
455+
}
456+
return false
457+
},
454458
}
455459
)
456460
.catch((error: any) => {

packages/core/src/shared/utilities/timeoutUtils.ts

Lines changed: 0 additions & 111 deletions
Original file line numberDiff line numberDiff line change
@@ -397,114 +397,3 @@ export function sleep(duration: number = 0): Promise<void> {
397397
const schedule = globals?.clock?.setTimeout ?? setTimeout
398398
return new Promise((r) => schedule(r, Math.max(duration, 0)))
399399
}
400-
401-
/**
402-
* Similar to waitUntil but with enhanced cancellation support.
403-
* Waits until the predicate returns true or the operation is cancelled.
404-
* Continuously checks for cancellation even when waiting for the next chunk.
405-
*
406-
* @param fn Function whose result is checked
407-
* @param options Configuration options including timeout, interval, and cancellation token
408-
* @returns Result of fn(), or undefined if cancelled
409-
*/
410-
export async function waitUntilWithCancellation<T>(
411-
fn: () => Promise<T>,
412-
options: WaitUntilOptions & {
413-
cancellationToken: CancellationToken
414-
}
415-
): Promise<T | undefined> {
416-
const { cancellationToken, ...waitOptions } = options
417-
418-
// Set up cancellation listener
419-
let cancellationListener: { dispose: () => void } | undefined
420-
let checkInterval: NodeJS.Timeout | number | undefined
421-
let isCancelled = false
422-
423-
try {
424-
return await new Promise<T | undefined>((resolve, reject) => {
425-
// Set up cancellation listener that will resolve with undefined instead of rejecting
426-
if (cancellationToken) {
427-
cancellationListener = cancellationToken.onCancellationRequested(() => {
428-
if (checkInterval) {
429-
globals.clock.clearInterval(checkInterval)
430-
}
431-
isCancelled = true
432-
resolve(undefined) // Resolve with undefined instead of rejecting
433-
})
434-
}
435-
436-
// Use the existing waitUntil function with a wrapper that checks for cancellation
437-
waitUntil(
438-
async () => {
439-
// Check for cancellation before executing function
440-
if (cancellationToken.isCancellationRequested) {
441-
isCancelled = true
442-
return undefined // Return undefined to signal cancellation
443-
}
444-
445-
const result = await fn()
446-
447-
// Check for cancellation after executing function
448-
if (cancellationToken.isCancellationRequested) {
449-
isCancelled = true
450-
return undefined // Return undefined to signal cancellation
451-
}
452-
453-
return result
454-
},
455-
{
456-
...waitOptions,
457-
retryOnFail: (error) => {
458-
// Don't retry if cancelled
459-
if (isCancelled) {
460-
return false
461-
}
462-
463-
// Use the original retryOnFail option if provided
464-
if (typeof waitOptions.retryOnFail === 'function') {
465-
return waitOptions.retryOnFail(error)
466-
}
467-
return waitOptions.retryOnFail ?? false
468-
},
469-
}
470-
)
471-
.then((result) => {
472-
// If cancelled during execution, resolve with undefined
473-
if (isCancelled) {
474-
resolve(undefined)
475-
} else {
476-
resolve(result)
477-
}
478-
})
479-
.catch((error) => {
480-
// If cancelled during execution, resolve with undefined
481-
if (isCancelled) {
482-
resolve(undefined)
483-
} else {
484-
reject(error)
485-
}
486-
})
487-
488-
// Set up an interval to periodically check for cancellation
489-
// This ensures we don't miss cancellation events while waiting for the next chunk
490-
checkInterval = globals.clock.setInterval(
491-
() => {
492-
if (cancellationToken.isCancellationRequested && !isCancelled) {
493-
isCancelled = true
494-
globals.clock.clearInterval(checkInterval)
495-
resolve(undefined) // Resolve with undefined instead of rejecting
496-
}
497-
},
498-
Math.min(waitOptions.interval ?? waitUntilDefaultInterval, 100)
499-
)
500-
})
501-
} finally {
502-
// Clean up resources
503-
if (checkInterval) {
504-
globals.clock.clearInterval(checkInterval)
505-
}
506-
if (cancellationListener) {
507-
cancellationListener.dispose()
508-
}
509-
}
510-
}

0 commit comments

Comments
 (0)