microsoft / microsoft/vscode-languageserver-node
Consider supporting/merging with the `cancellationtoken` npm package
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 1.8k
- Forks
- 404
- Avg merge
- 2d 8h
- Merged PRs (30d)
- 14
Description
vscode-jsonrpc defines its own CancellationToken interface which is modeled after the .NET type by the same name. While this is a fine type to use, it's tucked inside an RPC library which doesn't make it particularly nice to use in other settings.
There is a cancellationtoken npm package that focuses just on such a token. It is a more capable token, offering throwIfCancelled(), timeouts, optional reasons for cancellation, an api to race a token against another promise, and combining multiple tokens into one as a race or as a union of all. While it can do everything the .NET version can, the API is designed to be more javascript-esque, so it feels more native.
Given these two options, in some libraries I would tend to prefer the latter token. But where I have to interop with vscode-jsonrpc this complicates the story and leads to potential bugs when the wrong token is given or expected.
Can vscode-jsonrpc be updated to support this cancellationtoken npm package?
In particular, I'm thinking you could do duck-type checking to detect which kind it is and work with both. When creating a token to pass to RPC servers, perhaps you could create a token which fulfills the API obligations of both so that the RPC server can be implemented to receive either one.
Here are adapters I wrote that makes either token look like the other, to demonstrate how simple this is. Note that creating a union type to provide to RPC server methods would probably be more complicated.
import CancellationToken from 'cancellationtoken';
import {
CancellationToken as vscodeCancellationToken,
CancellationTokenSource as vscodeCancellationTokenSource,
} from 'vscode-jsonrpc';
export class CancellationTokenAdapters {
/** Tests whether an object satisfies the {@link vscodeCancellationToken} interface. */
static IsVSCode(value: any): value is vscodeCancellationToken {
return vscodeCancellationToken.is(value);
}
/** Tests whether an object satisfies the {@link CancellationToken} interface. */
static IsCancellationToken(value: any): value is CancellationToken {
return value
&& typeof value.throwIfCancelled === 'function'
&& typeof value.onCancelled === 'function'
&& value.isCancelled !== undefined
&& value.canBeCancelled !== undefined;
}
/** Returns a {@link CancellationToken} that is linked to the given {@link vscodeCancellationToken}. */
static VSCodeToCancellationToken(cancellationToken: vscodeCancellationToken): CancellationToken {
if (cancellationToken.isCancellationRequested) {
return CancellationToken.CANCELLED;
} else if (cancellationToken === vscodeCancellationToken.None) {
return CancellationToken.CONTINUE;
} else {
const result = CancellationToken.create();
cancellationToken.onCancellationRequested(_ => result.cancel());
return result.token;
}
}
/** Returns a {@link vscodeCancellationToken} that is linked to the given {@link CancellationToken}. */
static CancellationTokenToVSCode(cancellationToken: CancellationToken): vscodeCancellationToken {
if (cancellationToken.isCancelled) {
return vscodeCancellationToken.Cancelled;
} else if (cancellationToken.canBeCancelled) {
const cts = new vscodeCancellationTokenSource();
cancellationToken.onCancelled(_ => cts.cancel());
return cts.token;
} else {
return vscodeCancellationToken.None;
}
}
}
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reviewing the vscode-jsonrpc CancellationToken and CancellationTokenSource APIs, then compare them with the cancellationtoken package and the adapters shown in the issue. Done should mean vscode-jsonrpc can interoperate with both token shapes without breaking existing consumers, but the issue does not name files or tests to run.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- node.js, typescript
- Domain
- api
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100