From c091f25452ce5749cd65ecdfdbf70db5ccaf027f Mon Sep 17 00:00:00 2001 From: Tobias Ortmayr Date: Tue, 27 Sep 2022 15:32:58 -0700 Subject: [PATCH] Restore cancellation token behavior (#11693) Ensure that cancelling an RPC call does not result in an automatic rejection on the calling side. Instead the token is passed to the receiving side and handled there. This restores the cancellation strategy that was used with the old json-rpc architecture (prior to 1.28). Contributed on behalf of STMicroelectronics. --- .../src/common/message-rpc/rpc-protocol.ts | 22 +++++++------------ 1 file changed, 8 insertions(+), 14 deletions(-) diff --git a/packages/core/src/common/message-rpc/rpc-protocol.ts b/packages/core/src/common/message-rpc/rpc-protocol.ts index 6dfdbb125dad9..61be9c73d3881 100644 --- a/packages/core/src/common/message-rpc/rpc-protocol.ts +++ b/packages/core/src/common/message-rpc/rpc-protocol.ts @@ -132,23 +132,23 @@ export class RpcProtocol { // The last element of the request args might be a cancellation token. As these tokens are not serializable we have to remove it from the // args array and the `CANCELLATION_TOKEN_KEY` string instead. const cancellationToken: CancellationToken | undefined = args.length && CancellationToken.is(args[args.length - 1]) ? args.pop() : undefined; - if (cancellationToken && cancellationToken.isCancellationRequested) { - return Promise.reject(this.cancelError()); - } if (cancellationToken) { args.push(RpcProtocol.CANCELLATION_TOKEN_KEY); - cancellationToken.onCancellationRequested(() => { - this.sendCancel(id); - this.pendingRequests.get(id)?.reject(this.cancelError()); - } - ); } + this.pendingRequests.set(id, reply); const output = this.channel.getWriteBuffer(); this.encoder.request(output, id, method, args); output.commit(); + + if (cancellationToken?.isCancellationRequested) { + this.sendCancel(id); + } else { + cancellationToken?.onCancellationRequested(() => this.sendCancel(id)); + } + return reply.promise; } @@ -164,12 +164,6 @@ export class RpcProtocol { output.commit(); } - cancelError(): Error { - const error = new Error('"Request has already been canceled by the sender"'); - error.name = 'Cancel'; - return error; - } - protected handleCancel(id: number): void { const cancellationTokenSource = this.cancellationTokenSources.get(id); if (cancellationTokenSource) {