diff --git a/src/vs/workbench/contrib/positronNotebook/browser/notebookCells/DeferredImage.tsx b/src/vs/workbench/contrib/positronNotebook/browser/notebookCells/DeferredImage.tsx index 6decc5468a9..d6dd79ac1c7 100644 --- a/src/vs/workbench/contrib/positronNotebook/browser/notebookCells/DeferredImage.tsx +++ b/src/vs/workbench/contrib/positronNotebook/browser/notebookCells/DeferredImage.tsx @@ -10,8 +10,7 @@ import { URI } from 'vs/base/common/uri'; import { Schemas } from 'vs/base/common/network'; import { dirname } from 'vs/base/common/resources'; import { localize } from 'vs/nls'; -import { promiseWithTimeout } from '../../common/utils/promiseWithTimeout'; -import { CancellationTokenSource } from 'vs/base/common/cancellation'; +import { createCancelablePromise, raceTimeout } from 'vs/base/common/async'; /** * This should match the error message defined in the command definition @@ -65,15 +64,15 @@ export function DeferredImage({ src = 'no-source', ...props }: React.ComponentPr const conversionTimeoutMs = 3000; const errorTimeoutMs = 1000; - const tokenSource = new CancellationTokenSource(); let delayedErrorMsg: NodeJS.Timeout; - promiseWithTimeout( + const conversionCancellablePromise = createCancelablePromise(() => raceTimeout( services.commandService.executeCommand('positronNotebookHelpers.convertImageToBase64', src, baseLocation), - conversionTimeoutMs, - tokenSource.token - ).then((payload) => { + conversionTimeoutMs + )); + + conversionCancellablePromise.then((payload) => { if (typeof payload === 'string') { setResults({ status: 'success', data: payload }); } else if (isConversionErrorMsg(payload)) { @@ -96,7 +95,7 @@ export function DeferredImage({ src = 'no-source', ...props }: React.ComponentPr return () => { clearTimeout(delayedErrorMsg); - tokenSource.cancel(); + conversionCancellablePromise.cancel(); }; }, [src, baseLocation, services]); diff --git a/src/vs/workbench/contrib/positronNotebook/browser/notebookCells/Markdown.tsx b/src/vs/workbench/contrib/positronNotebook/browser/notebookCells/Markdown.tsx index 5ec77573617..5300cc8e7e2 100644 --- a/src/vs/workbench/contrib/positronNotebook/browser/notebookCells/Markdown.tsx +++ b/src/vs/workbench/contrib/positronNotebook/browser/notebookCells/Markdown.tsx @@ -9,8 +9,7 @@ import { DeferredImage } from './DeferredImage'; import { useServices } from 'vs/workbench/contrib/positronNotebook/browser/ServicesProvider'; import { ExternalLink } from 'vs/base/browser/ui/ExternalLink/ExternalLink'; import { localize } from 'vs/nls'; -import { promiseWithTimeout } from 'vs/workbench/contrib/positronNotebook/common/utils/promiseWithTimeout'; -import { CancellationTokenSource } from 'vs/base/common/cancellation'; +import { createCancelablePromise, raceTimeout } from 'vs/base/common/async'; /** * Component that render markdown content from a string. @@ -50,13 +49,12 @@ function useMarkdown(content: string): MarkdownRenderResults { React.useEffect(() => { - const tokenSource = new CancellationTokenSource(); - - promiseWithTimeout( + const conversionCancellablePromise = createCancelablePromise(() => raceTimeout( services.commandService.executeCommand('markdown.api.render', content), 5000, - tokenSource.token - ).then((html) => { + )); + + conversionCancellablePromise.then((html) => { if (typeof html !== 'string') { setRenderedHtml({ status: 'error', @@ -80,7 +78,7 @@ function useMarkdown(content: string): MarkdownRenderResults { }); }); - return () => tokenSource.cancel(); + return () => conversionCancellablePromise.cancel(); }, [content, services]); return renderedHtml; diff --git a/src/vs/workbench/contrib/positronNotebook/common/utils/promiseWithTimeout.ts b/src/vs/workbench/contrib/positronNotebook/common/utils/promiseWithTimeout.ts deleted file mode 100644 index c8220a5a26a..00000000000 --- a/src/vs/workbench/contrib/positronNotebook/common/utils/promiseWithTimeout.ts +++ /dev/null @@ -1,32 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (C) 2024 Posit Software, PBC. All rights reserved. - *--------------------------------------------------------------------------------------------*/ - -import { CancellationToken } from 'vs/base/common/cancellation'; - -/** - * Function to wrap a promise in a timeout. Also allows for the unsubscribing to the promise output. - * @param promise Promise to wrap. - * @param timeoutMs Timeout in milliseconds. - * @param cancelToken Token to cancel the promise as returned by `CancellationTokenSource.token`. - */ -export function promiseWithTimeout(promise: Promise, timeoutMs: number, cancelToken: CancellationToken): Promise { - - return new Promise((resolve, reject) => { - cancelToken.onCancellationRequested(() => { - reject(new Error('Promise cancelled')); - }); - - const timeout = setTimeout(() => { - reject(new Error(`Promise timed out after ${timeoutMs}ms`)); - }, timeoutMs); - - promise.then((res) => { - clearTimeout(timeout); - resolve(res); - }).catch((err) => { - clearTimeout(timeout); - reject(err); - }); - }); -}