-
Notifications
You must be signed in to change notification settings - Fork 13
Description
Describe the bug
Cancelling the client Task during a server-streaming RPC does not cancel the server-side handler: the server keeps successfully writing messages indefinitely. Neither Task.isCancelled
nor context.cancellation.isCancelled
becomes true during the call. Cancellation is only observed much later (when the graceful shutdown of the server starts).
Versions:
- grpc-swift: grpc-swift-2 v2.1.0 (
GRPCCore
,GRPCInProcessTransport
) - protoc-gen-grpc-swift: v2.1.1 (
grpc-swift-protobuf
) - swift-protobuf: v1.31.0
- Swift: Swift version 6.1 (swift-6.1-RELEASE), Target: aarch64-unknown-linux-gnu
- Platform: Ubuntu 24.04.2 LTS (Dev Container); also reproduces on macOS
- Build: swift run (debug)
- Transport: In-process (GRPCInProcessTransport)
We are experiencing this issue when using the Swift NIO based HTTP2 transport as well. In our production code, we have a set-up with an iOS app, that connects over gRPC to a backend ("app API"), which in turn connects to another backend over gRPC ("core API"). The entire codebase is built with GRPC Swift 2 (server and client). We're noticing that streams that are closed by the app aren't properly cancelled on the App API or Core API.
To reproduce
git clone https://github.com/Obbut/GRPC-Swift-2-cancellation.git
cd GRPC-Swift-2-cancellation
swift run
The repro project makes 3 requests to a server streaming RPC in series. Each request is cancelled (by cancelling the Task) before starting the next.
As should be evident by observing the logs, the cancellation is not correctly propagated to the server. The writer keeps succeeding.
Expected behaviour
- The server‑side handler observes cancellation promptly.
writer.write(...)
throws or the handler exits quickly.context.cancellation.isCancelled
and/orTask.isCancelled
becomes true for that call.- Per‑call resources are released (e.g., the
activeWriters
in the repro project returns to zero between calls).
Additional information
Repro project, main file: https://github.com/Obbut/GRPC-Swift-2-cancellation/blob/c597dc35930193a45cafb0addaba547037118158/Sources/GRPCSwift2Cancellation/main.swift
Repro project, service implementation: https://github.com/Obbut/GRPC-Swift-2-cancellation/blob/main/Sources/GRPCSwift2Cancellation/HelloWorldService.swift