[C#] Add cancellation token overloads to streaming interfaces#27886
Conversation
|
Error related to updating SDK: |
|
Unfortunately bumping the .NET SDK for Grpc.Core builds isn't that easy (more changes is needed in other places as well). I'd have to look into that separately. |
|
Note to self: Recent PR for upgrading the dotnet SDK: https://github.com/grpc/grpc/pull/26465/files |
|
I will look at this in detail once I successfully upgrade the dotnet SDK in the grpc/grpc repo: #27966 (it's proving difficult). |
|
SDK has been updated in #27966, you can rebase now. |
5d6b5b3 to
a0a5ee1
Compare
a0a5ee1 to
886a8c8
Compare
|
ping @jtattermusch |
jtattermusch
left a comment
There was a problem hiding this comment.
I wrote a few comments earlier, but forgot to hit "send", sorry for the delay.
See comments for concerns (To me it's unclear what the implementation would look like for Grpc.Core, and simply ignoring the cancellation token seems problematic).
Btw, in grpc/grpc-dotnet#1422 (comment) I pointed out that we are potentially missing a mechanism to cancel the entire call on the server side (on the client side cancelling a call is easy since you can pass cancellation token to a new call). One can "cancel" the server side call handler by simple throwing/returning from the handler function, but there is no other way.
Exposing overloads that take cancellationToken on individual write operations is basically just a proxy for cancelling the entire call, since the semantics of "cancel an individual write operation" is non-recoverable and the entire call will need to be cancelled anyway.
So perhaps we should first figure out the mechanism for cancelling the entire server side call (and expose it e.g. on ServerCallContext) after which adding the new WriteAsync overloads that take cancellationToken would become just syntactic sugar?
| /// </summary> | ||
| /// <param name="message">The message to be written. Cannot be null.</param> | ||
| /// <param name="cancellationToken">Cancellation token that can be used to cancel the operation.</param> | ||
| Task WriteAsync(T message, CancellationToken cancellationToken) |
There was a problem hiding this comment.
what is the intended behavior of the CancellationToken (if not CancellationToken.None) when on Grpc.Core and grpc-dotnet? I assume the plan is to trigger cancellation of the entire call if the cancellation token is triggered? (because there isn't much we can do otherwise). What is the plan for implementing that behavior in both Grpc.Core and grpc-dotnet?
There was a problem hiding this comment.
Kestrel supports aborting in-progress requests. I haven't looked into exactly how it will work but it will either be:
- The cancellation token is passed to the underlying writer and if the writer gets a cancellation then it will abort the request, or
- WriteAsync subscribes to the cancellation token with a callback that calls
HttpContext.Abort().
I don't know the internals of Grpc.Core.
There was a problem hiding this comment.
Grpc.Core
Would Grpc.Core cancellation be supported with this code:
grpc/src/csharp/Grpc.Core/Internal/AsyncCallBase.cs
Lines 393 to 399 in 8410142
It is used by IAsyncStreamReader<T>.MoveNext which takes a cancellation token:
grpc/src/csharp/Grpc.Core/Internal/ServerRequestStream.cs
Lines 50 to 58 in 2d4f3c5
It seems to me that what works for canceling while reading should also work for canceling while writing.
There was a problem hiding this comment.
Grpc.Core
Actually, Grpc.Core only supports up to netstandard20 and net45. The new overload is netstandard21 or later so won't be available.
886a8c8 to
d3971ec
Compare
|
@apolcyn please add another LGTM. |
|
Added "RELEASE BLOCKER" to make sure it gets included in the upcoming 1.45.x branch cut. The python and iOS binary size diff failures are unrelated (test flake and test infra timeout). |
See grpc/grpc-dotnet#1422 (comment)
@jtattermusch @captainsafia