dotnet / dotnet/orleans

Add GrainCancellationTokenSource.Cancel(CancellationToken) overload

Open
#8,634 0 comments 1 reaction 0 assignees View on GitHub
enhancement help wanted
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

Open the contributing 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.