grpc / grpc.github.io

The grpc.io website. (on GitHub pages)

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Clarify lifetime requirement of response object passed to ServerAsyncResponseWriter<T>::Finish()

arthur-tacca opened this issue · comments

In the implementation of an async C++ server, you will end up calling ServerAsyncResponseWriter<T>::Finish() in order to send a reply to the client. Here is the relevant line from the greeter_async_server:

responder_.Finish(reply_, Status::OK, this);

As context / a reminder: It is certainly necessary to ensure the lifetime of the ServerAsyncResponseWriter<T> object (i.e. responder_) extends until the tag is posted again to the completion queue. In that example the tag is this, and when it is posted to the completion queue it is deleted (because status_ == FINISH); the object responder_ is a data member, so that gets destroyed to.

My question is: Is it necessary to ensure the lifetime of the response object (i.e. reply_ in this example) also extends until the tag is posted again to the completion queue, or is it acceptable for it to be destroyed immediately after the call to Finish()? In other words, does Finish() immediately serialise the response to a buffer, or does it retain a pointer to the response. In the greeter example, reply_ is a data member of CallData so is destroyed at the same time as responder_, but it is not clear if that is necessary or an implementation detail. Ideally, the response to this question could be recorded in the async greeter documentation.

I realise I could just play it safe and keep the response object lying around, but there are a few undocumented things in the C++ async APIs, especially around object lifetimes and whatnot, so one less thing to guess at would be nice.

gRPC follows the style guide that it does not maintain a reference or a pointer to anything that's passed in with a const reference so reply_ can be safely destroyed immediately after it. You are right in thinking that internally we serialize it immediately