Open JavierAlvarezDH opened 2 years ago
Hmmm... This sort of failure is because an earlier error has been lost, letting through the garbage error. The stack trace is surprising, as 1) the code is looping through streams to close them with a good status yet 2) a later error is propagating to the RPC.
This error is happening for RPCs that lost a GOAWAY race; the server refused the stream after the client sent (part of) it. The client had some data still buffered waiting to be sent.
We do close gracefully (the false
) during the goaway, which means there might be some avenue for another status to sneak in:
https://github.com/grpc/grpc-java/blob/12984db6a7f5f322797d6a8d2cbd5a5938468d83/netty/src/main/java/io/grpc/netty/NettyClientHandler.java#L851-L852
But I'm not sure how this second error is being noticed. The DefaultHttp2RemoteFlowController is failing writes which will fail futures. The only place we care about failed futures is when creating the stream where we send headers. But I thought the Netty flow controller didn't handle headers (they are sent immediately). I wonder if there's any flows that could get headers queued in the flow controller.
We're using (indirectly via
spring-cloud-gcp-pubsub
)gRPC-Java 1.46.0
onOpenJDK 11 Debian Linux
and we've observed the following exceptions in our data pipeline:The "Internal" gRPC status is propagated to application code and force us to retry pull operation polluting logs with errors/warnings along the way.
To add more context this is happening when Pub/Sub PullRequest API takes long time (we're observing p99 20-30 seconds latency when this happens). Netty closes the connection with "Stream closed before write could take place" in DefaultHttp2RemoteFlowController.java:481 and status
io.netty.handler.codec.http2.Http2Error.STREAM_CLOSED(0x5)
Then this status code is translated to
io.grpc.internal.Http2Error.INTERNAL
and propagated up the stack.Is this internal error expected behaviour? If not, any recommendation on how to avoid these exceptions?
I've attached our dependency tree as reference. dependencies.txt