To ensure resources are not leaked due to the stream returned, one of the following actions must be performed:
Call Close on the ClientConn.
Cancel the context provided.
Call RecvMsg until a non-nil error is returned. A protobuf-generated client-streaming RPC, for instance, might use the helper function CloseAndRecv (note that CloseSend does not Recv, therefore is not guaranteed to release all resources).
Receive a non-nil, non-io.EOF error from Header or SendMsg.
However, the current implementation of instrumentedClientStream does not correctly handle choices 1 and 2: if the ClientConn is closed and no further action is taken with the stream, or if the context provided is cancelled, metrics for the request are not recorded.
This PR addresses this issue for choice 2 (context cancellation). The fix is inspired by opentracing-contrib/go-grpc's equivalent implementation: source
Fixing the issue for choice 1 (calling Close on ClientConn) is more involved, so in the interests of keeping this PR small, I've chosen to focus on just the context cancellation case here.
According to https://pkg.go.dev/google.golang.org/grpc#ClientConn.NewStream, it's safe to not call
Recv()
on agrpc.ClientStream
until it's exhausted if you clean up the stream in other ways:However, the current implementation of
instrumentedClientStream
does not correctly handle choices 1 and 2: if theClientConn
is closed and no further action is taken with the stream, or if the context provided is cancelled, metrics for the request are not recorded.This PR addresses this issue for choice 2 (context cancellation). The fix is inspired by
opentracing-contrib/go-grpc
's equivalent implementation: sourceFixing the issue for choice 1 (calling
Close
onClientConn
) is more involved, so in the interests of keeping this PR small, I've chosen to focus on just the context cancellation case here.