-
-
Notifications
You must be signed in to change notification settings - Fork 3
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
[feature]: Support cancellation #16
Comments
@dankeboy36 |
Preferably the handler at the extension side. Of course, it should be the responsibility of the extension developer to abort the actual work, but the cancellation signal ( Here is my pseudo-example of a useful feature. I wrote it by hand. Maybe it does not even compile.
import type { RequestType } from 'vscode-messenger-common';
export interface SearchParams {
readonly query: string;
}
export interface SearchResult = readonly string[]
export const searchType: RequestType<SearchParams, SearchResult> = { method: 'search' };
import { CancellationToken, ExtensionContext } from 'vscode';
import { Messenger } from 'vscode-messenger';
import { searchType } from '@my-app/protocol';
export function activate(context: ExtensionContext) {
const messenger = new Messenger({ ignoreHiddenViews: false, debugLog: true });
// create the webview panel
// register the webview panel to the messenger
// register other commands, views, and disposables
context.subscriptions.push(messenger.onRequest(searchType, async (params, sender, cancellationToken: CancellationToken) => {
const abortController = new AbortController();
const { signal } = abortController;
const toDispose = cancellationToken.onCancellationRequested(abortController => abortController.abort());
const { execa } = await import('execa');
try {
// this is just a made-up example. imagine any service call that can be interrupted.
// https://www.npmjs.com/package/execa#signal
const { stdout } = await execa('grep', ['-rl', params.query], { signal });
return stdout.split('\n');
} catch (err) {
if (isExecaError(err) && err.isCanceled) {
return [];
}
throw err;
} finally {
toDispose.dispose();
}
}));
return messenger.diagnosticApi();
}
import { TextField } from '@vscode/webview-ui-toolkit';
import { VSCodeTextField } from '@vscode/webview-ui-toolkit/react';
import { searchType } from '@my-app/protocol';
import { useEffect, useState } from 'react';
import { Virtuoso } from 'react-virtuoso';
import { HOST_EXTENSION } from 'vscode-messenger-common';
import './App.css';
import { vscode } from './utilities/vscode';
function App() {
const [query, setQuery] = useState<string>('')
const [data, setData] = useState<string[]>([])
useEffect(() => {
const abortController = new window.AbortController();
const signal = abortController.signal;
async function runQuery() {
const result = await vscode.messenger.sendRequest(searchType, HOST_EXTENSION, query, { signal });
setData(result)
}
runQuery()
return () => {
if (signal && abortController.abort) {
abortController.abort();
}
};
}, [query])
return (
<main>
<VSCodeTextField value={query} onInput={event => {
if (event.target instanceof TextField) {
setQuery(event.target.value);
}
}}/>
<Virtuoso
data={data}
itemContent={(index, line) => (
<div>
<div>{line}</div>
</div>
)}
/>
</main>
);
}
export default App; |
@dankeboy36 |
Request handler now has an additional parameter export type RequestHandler<P, R> =
(params: P, sender: MessageParticipant, cancelIndicator: CancelIndicator) => HandlerResult<R>; CancelIndicator can be asked for the cancelation state or one can set the callback function export interface CancelIndicator {
isCanceled(): boolean;
onCancel: ((reason: string) => void) | undefined;
} On the sender side Simple timeout example: const cancelable = new vscode_messenger_common.Cancelable();
setTimeout(() => cancelable.cancel('Timeout: 1 sec'), 1000);
const colors = await messenger.sendRequest(
{ method: 'availableColor' },
{ type: 'extension' },
'',
cancelable
); The code is currently on a branch |
Absolutely, I have been monitoring your changes. Very nice, thank you! Is there a reason this lib invents its own |
New version |
Thanks for the lib ❤️
Support cancellation. Maybe with
AbortSignal
. It's available in the browser and from Node.js 15+: https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal#browser_compatibilityThe text was updated successfully, but these errors were encountered: