C++ client streaming RPC: How to detect sever-side stream termination on the client?

962 views
Skip to first unread message

Norman Link

unread,
Mar 23, 2018, 11:47:04 AM3/23/18
to grpc.io
Hello,

I have a client to server stream defined as

rpc ClientStream(stream Request) returns (Response);

Both server and client are implemented in C++. The client sends a number of requests to the server, which may then close the stream based on some condition. When doing so, the server calls Finish() on ServerAsyncReader and sends the result.

However, this result is never received on the client, since ClientAsyncReader provides no interface or callback to determine that the server closed the stream. Also, the completion queue does not return ok = false on the Write() operation. So in this case, my client just keeps on sending data to the server, although nobody is listening anymore.

What is the suggested way to detect server-side stream termination?

Best regards,
Norman Link

Vijay Pai

unread,
Apr 9, 2018, 6:42:00 PM4/9/18
to grpc.io
Hello there,

Thanks for posting this. We _should_ make sure that the behavior here is such that Write returns ok=false if the server side has sent status (even if the client-side hasn't yet received that status).  Although we've currently said that an ok=true on Write just means that the Write has made it into the flow-control buffers, this is a clear case where the flow-control buffer will never get meaningfully emptied, so it's as though it didn't actually pass flow control. Can I suggest that you file a github issue about your problem, preferably along with any code that would be needed to help us repro/test/track/triage it?

Thanks!

-vjpai

PS: That said, I think there should be strong caveats when using client-side streaming. Even if we change the behavior as I described, there's still no protocol-level way of knowing how many of the client-side write operations were actually read by the server. The service should generally define its response proto in such a way as to provide that information back to the client at the application-level.

Norman Link

unread,
Apr 12, 2018, 3:17:29 AM4/12/18
to grpc.io
Hello Vjpai,

Thanks for your answer. I created issue 14812 here:

I raised this issue because one of the main assumptions of gRPC is that both server and client can cancel a stream at any time. I.e., a server that has received "enough" items should be able to tell the client to stop sending. Cancelling a stream is an implicit operation and should not require an explicit flag in some message. In case of a client to server stream, this would not even be possible. Since there is only one response message flowing from server to client, a server has no way to communicate with a client and tell him: "Now please stop sending and wait for my status".

I wouldn't really care how this is implemented. Returning ok=false on the completion queue was my assumption, because the documentation for the synchronous implementation indicates it should return false. Following ok=false, a client would need to call Finish() to receive the status from the server.

I will add some code examples for repro to the issue soon.

Best regards,
Norman

ple...@swissonline.ch

unread,
Nov 21, 2018, 11:07:56 AM11/21/18
to grpc.io

Hi,

I face the same issue, and read the whole discussion on github. 

What is the status ? Does the behaviour changes regarding which grpc version we are using ?

Thanks

Philippe Leuba
Reply all
Reply to author
Forward
0 new messages