Path: blob/main/extensions/copilot/src/util/common/racePromise.ts
13397 views
/*---------------------------------------------------------------------------------------------1* Copyright (c) Microsoft Corporation. All rights reserved.2* Licensed under the MIT License. See License.txt in the project root for license information.3*--------------------------------------------------------------------------------------------*/45import { raceCancellation, raceTimeout } from '../vs/base/common/async';6import { CancellationToken, CancellationTokenSource } from '../vs/base/common/cancellation';7import { CancellationError } from '../vs/base/common/errors';89// sentinel value to indicate cancellation10const CANCELLED = Symbol('cancelled');1112/**13* Races a promise against a cancellation token and a timeout.14* @param promiseGenerator A function that generates the promise to race against cancellation and timeout.15* @param parentToken The cancellation token to use.16* @param timeoutInMs The timeout in milliseconds.17* @param timeoutMessage The message to use for the timeout error.18* @returns The result of the promise if it completes before the timeout, or throws an error if it times out or is cancelled.19*/20export async function raceTimeoutAndCancellationError<T>(21promiseGenerator: (cancellationToken: CancellationToken) => Promise<T>,22parentToken: CancellationToken,23timeoutInMs: number,24timeoutMessage: string): Promise<T> {25const cancellationSource = new CancellationTokenSource(parentToken);26try {27const result = await raceTimeout(raceCancellation(promiseGenerator(cancellationSource.token), cancellationSource.token, CANCELLED as T), timeoutInMs);2829if (result === CANCELLED) { // cancelled sentinel from raceCancellation30throw new CancellationError();31}3233if (result === undefined) { // timeout sentinel from raceTimeout34// signal ongoing work to cancel in the promise35cancellationSource.cancel();36throw new Error(timeoutMessage);37}3839return result;40}41finally {42cancellationSource.dispose();43}44}4546