Add GrainCancellationTokenSource.Cancel(CancellationToken) overload
- Dominant language
- C#
- Stars
- 10.9k
- Forks
- 2.1k
- Avg merge
- 14h 42m
- Merged PRs (30d)
- 354
Description
The `Task` returned by the `GrainCancellationTokenSource.Cancel` method does not complete until the cancellations sent to all in-progress grain methods invoked using a `GrainCancellationToken` attached to the `GrainCancellationTokenSource` all successfully complete, which I assume means once all cancellation messages have been acknowledged. This is a network operation subject to delays and timeouts, which means that the operation could take a long time to complete. Therefore, the operation should be cancelable.
I therefore propose that a `GrainCancellationTokenSource.Cancel(CancellationToken)` overload be added.
The cancellation operation should be immediately abandoned as soon as the given `CancellationToken` parameter is signaled. i.e., cancelling the cancellation operation does not mean sending cancellation messages to cancel the previously sent cancellation messages. It simply means to stop waiting for the previously sent cancellation messages to be acknowledged. Therefore, when the given `CancellationToken` parameter is signaled:
1. Any client-side in-progress grain method calls using a `GrainCancellationToken` attached to the `GrainCancellationTokenSource` all immediately complete, throwing an `OperationCanceledException`.
2. The `GrainCancellationTokenSource.Cancel` method immediately completes, throwing an `OperationCanceledException`.
Note that stopping an ASP.NET Core host process is signaled with two cancellation tokens. The first token is signaled when the host's `StopAsync(CancellationToken)` method is invoked and the second if/when the `CancellationToken` parameter passed to the `StopAsync(CancellationToken)` is canceled. It would make sense that the `GrainCancellationTokenSource.Cancel(CancellationToken)` method be invoked when the first cancellation token is signaled, passing the second cancellation token as the method parameter.
This would also allow grain methods to be instantly cancelled on the client side without sending cancellation messages or waiting for those messages to be acknowledged by invoking `GrainCancellationTokenSource.Cancel(new(canceled: true))`. It would also allow enforcing a timeout:
```csharp
using var gcts = new GrainCancellationTokenSource();
// Invoke grain method(s)
// Cancel grain method(s) with a five second timeout.
var timeout = TimeSpan.FromSeconds(5);
using var cts = new CancellationTokenSource(timeout);
await gcts.Cancel(cts.Token);
```
Contributor guide
Research direction
Start at GrainCancellationTokenSource.Cancel and trace how GrainCancellationToken cancellation acknowledgements are handled. Compare the proposed overload behavior with StopAsync(CancellationToken), then verify that cancellation stops waiting, completes affected client-side calls, and produces OperationCanceledException as described.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- csharp
- Domain
- distributed-systems
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100