diff --git a/include/grpc++/generic/generic_stub.h b/include/grpc++/generic/generic_stub.h index 3c11e550018..fdd23772043 100644 --- a/include/grpc++/generic/generic_stub.h +++ b/include/grpc++/generic/generic_stub.h @@ -50,7 +50,11 @@ class GenericStub final { explicit GenericStub(std::shared_ptr channel) : channel_(channel) {} - /// begin a call to a named method + /// Begin a call to a named method \a method usign \a context. + /// A tag \a tag will be deliever to \a cq when the call has been started + /// (i.e, initial metadata has been sent). + /// The return value only indicates whether or not registration of the call + /// succeeded (i.e. the call won't proceed if the return value is 0). std::unique_ptr Call( ClientContext* context, const grpc::string& method, CompletionQueue* cq, void* tag); diff --git a/include/grpc++/grpc++.h b/include/grpc++/grpc++.h index daecfea4069..978b172346c 100644 --- a/include/grpc++/grpc++.h +++ b/include/grpc++/grpc++.h @@ -34,14 +34,18 @@ /// \mainpage gRPC C++ API /// /// The gRPC C++ API mainly consists of the following classes: +// /// - grpc::Channel, which represents the connection to an endpoint. See [the /// gRPC Concepts page](http://www.grpc.io/docs/guides/concepts.html) for more /// details. Channels are created by the factory function grpc::CreateChannel. +// /// - grpc::CompletionQueue, the producer-consumer queue used for all /// asynchronous communication with the gRPC runtime. +// /// - grpc::ClientContext and grpc::ServerContext, where optional configuration /// for an RPC can be set, such as setting custom metadata to be conveyed to the /// peer, compression settings, authentication, etc. +// /// - grpc::Server, representing a gRPC server, created by grpc::ServerBuilder. /// /// Streaming calls are handled with the streaming classes in diff --git a/include/grpc++/impl/codegen/async_stream.h b/include/grpc++/impl/codegen/async_stream.h index 39f0ebd86fa..5a685cbe554 100644 --- a/include/grpc++/impl/codegen/async_stream.h +++ b/include/grpc++/impl/codegen/async_stream.h @@ -58,11 +58,31 @@ class ClientAsyncStreamingInterface { /// \param[in] tag Tag identifying this request. virtual void ReadInitialMetadata(void* tag) = 0; - /// Indicate that the stream is to be finished and request notification - /// Should not be used concurrently with other operations + /// Indicate that the stream is to be finished and request notification for + /// when the call has been ended. + /// Should not be used concurrently with other operations. + /// + /// It is appropriate to call this method when both: + /// * the client side has no more message to send (this can be declared implicitly + /// by calling this method, or explicitly through an earlier call to \a + /// WritesDone. + /// * there are no more messages to be received from the server (which can + /// be known implicitly by the calling code, or known explicitly from an + /// earlier call to \a Read that yielded a failed result + /// (e.g. cq->Next(&read_tag, &ok) filled in 'ok' with 'false'. + /// + /// This function will return when either: + /// - all incoming messages have been read and the server has returned + /// a status. + /// - the server has returned a non-OK status. + /// - the call failed for some reason and the library generated a + /// status. + /// + /// Note that implementations of this method attempt to receive initial metadata + /// from the server if initial metadata hasn't yet been received. /// - /// \param[out] status To be updated with the operation status. /// \param[in] tag Tag identifying this request. + /// \param[out] status To be updated with the operation status. virtual void Finish(Status* status, void* tag) = 0; }; @@ -82,6 +102,9 @@ class AsyncReaderInterface { /// /// \param[out] msg Where to eventually store the read message. /// \param[in] tag The tag identifying the operation. + /// + /// Side effect: note that this method attempt to receive initial metadata for a stream if it + /// hasn't yet been received. virtual void Read(R* msg, void* tag) = 0; }; @@ -140,10 +163,16 @@ template class ClientAsyncReaderInterface : public ClientAsyncStreamingInterface, public AsyncReaderInterface {}; +/// Async client-side API for doing server-streaming RPCs, +/// where the incoming message stream coming from the server has messages of type \a R. template class ClientAsyncReader final : public ClientAsyncReaderInterface { public: /// Create a stream and write the first request out. + /// \a tag will be notified on \a cq when the call has been started and + /// \a request has been written out. + /// Note that \a context will be used to fill in custom initial metadata + /// used to send to the server when starting the call. template static ClientAsyncReader* Create(ChannelInterface* channel, CompletionQueue* cq, const RpcMethod& method, @@ -155,11 +184,19 @@ class ClientAsyncReader final : public ClientAsyncReaderInterface { ClientAsyncReader(call, context, request, tag); } - /// always allocated against a call arena, no memory free required + // always allocated against a call arena, no memory free required static void operator delete(void* ptr, std::size_t size) { assert(size == sizeof(ClientAsyncReader)); } + /// See the \a ClientAsyncStreamingInterface.ReadInitialMetadata method for + /// semantics. + /// + /// Side effect: + /// - upon receiving initial metadata from the server, + /// the \a ClientContext associated with this call is updated, and the + /// calling code can access the received metadata through the + /// \a ClientContext. void ReadInitialMetadata(void* tag) override { GPR_CODEGEN_ASSERT(!context_->initial_metadata_received_); @@ -168,6 +205,7 @@ class ClientAsyncReader final : public ClientAsyncReaderInterface { call_.PerformOps(&meta_ops_); } + /// See the \a AsyncReaderInterface.Read method for semantics of this method. void Read(R* msg, void* tag) override { read_ops_.set_output_tag(tag); if (!context_->initial_metadata_received_) { @@ -177,6 +215,11 @@ class ClientAsyncReader final : public ClientAsyncReaderInterface { call_.PerformOps(&read_ops_); } + /// See the \a ClientAsyncStreamingInterface.Finish method for semantics. + /// + /// Side effect: + /// - the \a ClientContext associated with this call is updated with + /// possible initial and trailing metadata received from the server. void Finish(Status* status, void* tag) override { finish_ops_.set_output_tag(tag); if (!context_->initial_metadata_received_) { @@ -214,16 +257,26 @@ template class ClientAsyncWriterInterface : public ClientAsyncStreamingInterface, public AsyncWriterInterface { public: - /// Signal the client is done with the writes. + /// Signal the client is done with the writes (half-close the client stream). /// Thread-safe with respect to \a Read /// /// \param[in] tag The tag identifying the operation. virtual void WritesDone(void* tag) = 0; }; +/// Async API to on the client side for doing client-streaming RPCs, +/// where the outgoing message stream going to the server contains messages of type \a W. template class ClientAsyncWriter final : public ClientAsyncWriterInterface { public: + /// Create a stream and write the first request out. + /// \a tag will be notified on \a cq when the call has been started (i.e. + /// intitial metadata sent) and \a request has been written out. + /// Note that \a context will be used to fill in custom initial metadata + /// used to send to the server when starting the call. + /// \a response will be filled in with the single expected response + /// message from the server upon a successful call to the \a Finish + /// method of this instance. template static ClientAsyncWriter* Create(ChannelInterface* channel, CompletionQueue* cq, const RpcMethod& method, @@ -235,11 +288,19 @@ class ClientAsyncWriter final : public ClientAsyncWriterInterface { ClientAsyncWriter(call, context, response, tag); } - /// always allocated against a call arena, no memory free required + // always allocated against a call arena, no memory free required static void operator delete(void* ptr, std::size_t size) { assert(size == sizeof(ClientAsyncWriter)); } + /// See the \a ClientAsyncStreamingInterface.ReadInitialMetadata method for + /// semantics. + /// + /// Side effect: + /// - upon receiving initial metadata from the server, + /// the \a ClientContext associated with this call is updated, and the + /// calling code can access the received metadata through the + /// \a ClientContext. void ReadInitialMetadata(void* tag) override { GPR_CODEGEN_ASSERT(!context_->initial_metadata_received_); @@ -248,6 +309,8 @@ class ClientAsyncWriter final : public ClientAsyncWriterInterface { call_.PerformOps(&meta_ops_); } + /// See the \a AsyncWriterInterface.Write(const W& msg, void* tag) + /// method for semantics of this method. void Write(const W& msg, void* tag) override { write_ops_.set_output_tag(tag); // TODO(ctiller): don't assert @@ -255,6 +318,9 @@ class ClientAsyncWriter final : public ClientAsyncWriterInterface { call_.PerformOps(&write_ops_); } + /// See the + /// \a AsyncWriterInterface.Write(const W& msg, WriteOptions options, void* tag) + /// method for semantics of this method. void Write(const W& msg, WriteOptions options, void* tag) override { write_ops_.set_output_tag(tag); if (options.is_last_message()) { @@ -266,12 +332,21 @@ class ClientAsyncWriter final : public ClientAsyncWriterInterface { call_.PerformOps(&write_ops_); } + /// See the \a ClientAsyncWriterInterface.WritesDone method for semantics of + /// this method. void WritesDone(void* tag) override { write_ops_.set_output_tag(tag); write_ops_.ClientSendClose(); call_.PerformOps(&write_ops_); } + /// See the \a ClientAsyncStreamingInterface.Finish method for semantics. + /// + /// Side effect: + /// - the \a ClientContext associated with this call is updated with + /// possible initial and trailing metadata received from the server. + /// - attempts to fill in the \a response parameter passed to this class's + /// constructor with the server's response message. void Finish(Status* status, void* tag) override { finish_ops_.set_output_tag(tag); if (!context_->initial_metadata_received_) { @@ -310,23 +385,33 @@ class ClientAsyncWriter final : public ClientAsyncWriterInterface { finish_ops_; }; -/// Client-side interface for asynchronous bi-directional streaming. +/// Async client-side interface for bi-directional streaming, +/// where the client-to-server message stream has messages of type \a W, +/// abnd the server-to-client message stream has messages of type \a R. template class ClientAsyncReaderWriterInterface : public ClientAsyncStreamingInterface, public AsyncWriterInterface, public AsyncReaderInterface { public: - /// Signal the client is done with the writes. + /// Signal the client is done with the writes (half-close the client stream). /// Thread-safe with respect to \a Read /// /// \param[in] tag The tag identifying the operation. virtual void WritesDone(void* tag) = 0; }; +/// Async client-side interface for bi-directional streaming, +/// where the outgoing message stream going to the server has messages of type \a W, +/// and the incoming message stream coming from the server has messages of type \a R. template class ClientAsyncReaderWriter final : public ClientAsyncReaderWriterInterface { public: + /// Create a stream and write the first request out. + /// \a tag will be notified on \a cq when the call has been started (i.e. + /// intitial metadata sent). + /// Note that \a context will be used to fill in custom initial metadata + /// used to send to the server when starting the call. static ClientAsyncReaderWriter* Create(ChannelInterface* channel, CompletionQueue* cq, const RpcMethod& method, @@ -338,11 +423,18 @@ class ClientAsyncReaderWriter final ClientAsyncReaderWriter(call, context, tag); } - /// always allocated against a call arena, no memory free required + // always allocated against a call arena, no memory free required static void operator delete(void* ptr, std::size_t size) { assert(size == sizeof(ClientAsyncReaderWriter)); } + /// See the \a ClientAsyncStreamingInterface.ReadInitialMetadata method + /// for semantics of this method. + /// + /// Side effect: + /// - upon receiving initial metadata from the server, the \a ClientContext + /// is updated with it, and then the receiving initial metadata can + /// be accessed through this \a ClientContext void ReadInitialMetadata(void* tag) override { GPR_CODEGEN_ASSERT(!context_->initial_metadata_received_); @@ -351,6 +443,8 @@ class ClientAsyncReaderWriter final call_.PerformOps(&meta_ops_); } + /// See \a AsyncReaderInterface.Read method for semantics + /// of this method. void Read(R* msg, void* tag) override { read_ops_.set_output_tag(tag); if (!context_->initial_metadata_received_) { @@ -360,6 +454,8 @@ class ClientAsyncReaderWriter final call_.PerformOps(&read_ops_); } + /// See \a AsyncWriterInterface.Write(const W& msg, void* tag) method for + /// semantics of this method. void Write(const W& msg, void* tag) override { write_ops_.set_output_tag(tag); // TODO(ctiller): don't assert @@ -367,6 +463,8 @@ class ClientAsyncReaderWriter final call_.PerformOps(&write_ops_); } + /// See \a AsyncWriterInterface.Write(const W& msg, WriteOptions options, void* tag) + /// method for semantics of this method. void Write(const W& msg, WriteOptions options, void* tag) override { write_ops_.set_output_tag(tag); if (options.is_last_message()) { @@ -378,12 +476,18 @@ class ClientAsyncReaderWriter final call_.PerformOps(&write_ops_); } + /// See \a ClientAsyncReaderWriterInterface.WritesDone method for semantics + /// of this method. void WritesDone(void* tag) override { write_ops_.set_output_tag(tag); write_ops_.ClientSendClose(); call_.PerformOps(&write_ops_); } + /// See the \a ClientAsyncStreamingInterface.Finish method for semantics. + /// Side effect + /// - the \a ClientContext associated with this call is updated with + /// possible initial and trailing metadata sent from the server. void Finish(Status* status, void* tag) override { finish_ops_.set_output_tag(tag); if (!context_->initial_metadata_received_) { @@ -422,17 +526,66 @@ template class ServerAsyncReaderInterface : public ServerAsyncStreamingInterface, public AsyncReaderInterface { public: + /// Indicate that the stream is to be finished with a certain status code + /// and also send out \a msg response to the client. + /// Request notification for when the server has sent the response and the appropriate + /// signals to the client to end the call. + /// Should not be used concurrently with other operations. + /// + /// It is appropriate to call this method when: + /// * all messages from the client have been received (either known + /// implictly, or explicitly because a previous \a Read operation + /// with a non-ok result (e.g., cq->Next(&read_tag, &ok) filled in 'ok' + /// with 'false'. + /// + /// This operation will end when the server has finished sending out initial metadata + /// (if not sent already), repsonse message, and status, or if some failure + /// occurred when trying to do so. + /// + /// \param[in] tag Tag identifying this request. + /// \param[in] status To be sent to the client as the result of this call. + /// \param[in] msg To be sent to the client as the response for this call. virtual void Finish(const W& msg, const Status& status, void* tag) = 0; + /// Indicate that the stream is to be finished with a certain non-OK status code. + /// Request notification for when the server has sent the appropriate + /// signals to the client to end the call. + /// Should not be used concurrently with other operations. + /// + /// This call is meant to end the call with some error, and can be called at + /// any point that the server would like to "fail" the call (though note + /// this shouldn't be called concurrently with any other "sending" call, like + /// \a Write. + /// + /// This operation will end when the server has finished sending out initial metadata + /// (if not sent already), and status, or if some failure + /// occurred when trying to do so. + /// + /// \param[in] tag Tag identifying this request. + /// \param[in] status To be sent to the client as the result of this call. + /// - Note: \a status must have a non-OK code. virtual void FinishWithError(const Status& status, void* tag) = 0; }; +/// Async server-side API for doing client-streaming RPCs, +/// where the incoming message stream from the client has messages of type \a R, +/// and the single response message sent from the server is type \a W. template class ServerAsyncReader final : public ServerAsyncReaderInterface { public: explicit ServerAsyncReader(ServerContext* ctx) : call_(nullptr, nullptr, nullptr), ctx_(ctx) {} + /// Request notification of the sending of initial metadata to the client. Completion + /// will be notified by \a tag on the associated completion queue. + /// This call is optional, but if it is used, it cannot be used concurrently + /// with or after the \a Finish method. + /// + /// Implicit input parameter: + /// - The initial metadata that will be sent to the client from this op will be + /// taken from the \a ServerContext associated with the call. + /// + /// \param[in] tag Tag identifying this request. void SendInitialMetadata(void* tag) override { GPR_CODEGEN_ASSERT(!ctx_->sent_initial_metadata_); @@ -446,12 +599,21 @@ class ServerAsyncReader final : public ServerAsyncReaderInterface { call_.PerformOps(&meta_ops_); } + /// See the \a AsyncReaderInterface.Read method for semantics. void Read(R* msg, void* tag) override { read_ops_.set_output_tag(tag); read_ops_.RecvMessage(msg); call_.PerformOps(&read_ops_); } + /// See the \a ServerAsyncReaderInterface.Read method for semantics + /// + /// Side effect: + /// - also sends initial metadata if not alreay sent. + /// - uses the \a ServerContext associated with this call to send possible + /// initial and trailing metadata. + /// + /// Note: \a msg is not sent if \a status has a non-OK code. void Finish(const W& msg, const Status& status, void* tag) override { finish_ops_.set_output_tag(tag); if (!ctx_->sent_initial_metadata_) { @@ -472,6 +634,12 @@ class ServerAsyncReader final : public ServerAsyncReaderInterface { call_.PerformOps(&finish_ops_); } + /// See the \a ServerAsyncReaderInterface.Read method for semantics + /// + /// Side effect: + /// - also sends initial metadata if not alreay sent. + /// - uses the \a ServerContext associated with this call to send possible + /// initial and trailing metadata. void FinishWithError(const Status& status, void* tag) override { GPR_CODEGEN_ASSERT(!status.ok()); finish_ops_.set_output_tag(tag); @@ -503,6 +671,24 @@ template class ServerAsyncWriterInterface : public ServerAsyncStreamingInterface, public AsyncWriterInterface { public: + /// Indicate that the stream is to be finished with a certain status code. + /// Request notification for when the server has sent the appropriate + /// signals to the client to end the call. + /// Should not be used concurrently with other operations. + /// + /// It is appropriate to call this method when either: + /// * all messages from the client have been received (either known + /// implictly, or explicitly because a previous \a Read operation + /// with a non-ok result (e.g., cq->Next(&read_tag, &ok) filled in 'ok' + /// with 'false'. + /// * it is desired to end the call early with some non-OK status code. + /// + /// This operation will end when the server has finished sending out initial metadata + /// (if not sent already), repsonse message, and status, or if some failure + /// occurred when trying to do so. + /// + /// \param[in] tag Tag identifying this request. + /// \param[in] status To be sent to the client as the result of this call. virtual void Finish(const Status& status, void* tag) = 0; /// Request the writing of \a msg and coalesce it with trailing metadata which @@ -520,12 +706,24 @@ class ServerAsyncWriterInterface : public ServerAsyncStreamingInterface, const Status& status, void* tag) = 0; }; +/// Async server-side API for doing server streaming RPCs, +/// where the outgoing message stream from the server has messages of type \a W. template class ServerAsyncWriter final : public ServerAsyncWriterInterface { public: explicit ServerAsyncWriter(ServerContext* ctx) : call_(nullptr, nullptr, nullptr), ctx_(ctx) {} + /// Request notification of the sending the initial metadata to the client. Completion + /// will be notified by \a tag on the associated completion queue. + /// This call is optional, but if it is used, it cannot be used concurrently + /// with or after the \a Finish method. + /// + /// Implicit input parameter: + /// - The initial metadata that will be sent to the client from this op will be + /// taken from the \a ServerContext associated with the call. + /// + /// \param[in] tag Tag identifying this request. void SendInitialMetadata(void* tag) override { GPR_CODEGEN_ASSERT(!ctx_->sent_initial_metadata_); @@ -539,6 +737,7 @@ class ServerAsyncWriter final : public ServerAsyncWriterInterface { call_.PerformOps(&meta_ops_); } + /// See the \a AsyncWriterInterface.Write(const W &msg, void *tag) method for semantics. void Write(const W& msg, void* tag) override { write_ops_.set_output_tag(tag); EnsureInitialMetadataSent(&write_ops_); @@ -547,6 +746,7 @@ class ServerAsyncWriter final : public ServerAsyncWriterInterface { call_.PerformOps(&write_ops_); } + /// See the \a AsyncWriterInterface.Write(const W &msg, WriteOptions options, void *tag) method for semantics. void Write(const W& msg, WriteOptions options, void* tag) override { write_ops_.set_output_tag(tag); if (options.is_last_message()) { @@ -559,6 +759,13 @@ class ServerAsyncWriter final : public ServerAsyncWriterInterface { call_.PerformOps(&write_ops_); } + /// See the \a ServerAsyncWriterInterface.WriteAndFinish method for semantics. + /// + /// Implicit input parameter: + /// - the \a ServerContext associated with this call is used + /// for sending trailing (and initial) metadata to the client. + /// + /// Note: \a status must have an OK code. void WriteAndFinish(const W& msg, WriteOptions options, const Status& status, void* tag) override { write_ops_.set_output_tag(tag); @@ -569,6 +776,13 @@ class ServerAsyncWriter final : public ServerAsyncWriterInterface { call_.PerformOps(&write_ops_); } + /// See the \a ServerAsyncWriterInterface.Finish method for semantics. + /// + /// Implicit input parameter: + /// - the \a ServerContext associated with this call is used + /// for sending trailing (and initial if not already sent) metadata to the client. + /// + /// Note: there are no restrictions are the code of \a status, it may be non-OK void Finish(const Status& status, void* tag) override { finish_ops_.set_output_tag(tag); EnsureInitialMetadataSent(&finish_ops_); @@ -606,6 +820,24 @@ class ServerAsyncReaderWriterInterface : public ServerAsyncStreamingInterface, public AsyncWriterInterface, public AsyncReaderInterface { public: + /// Indicate that the stream is to be finished with a certain status code. + /// Request notification for when the server has sent the appropriate + /// signals to the client to end the call. + /// Should not be used concurrently with other operations. + /// + /// It is appropriate to call this method when either: + /// * all messages from the client have been received (either known + /// implictly, or explicitly because a previous \a Read operation + /// with a non-ok result (e.g., cq->Next(&read_tag, &ok) filled in 'ok' + /// with 'false'. + /// * it is desired to end the call early with some non-OK status code. + /// + /// This operation will end when the server has finished sending out initial metadata + /// (if not sent already), repsonse message, and status, or if some failure + /// occurred when trying to do so. + /// + /// \param[in] tag Tag identifying this request. + /// \param[in] status To be sent to the client as the result of this call. virtual void Finish(const Status& status, void* tag) = 0; /// Request the writing of \a msg and coalesce it with trailing metadata which @@ -623,6 +855,9 @@ class ServerAsyncReaderWriterInterface : public ServerAsyncStreamingInterface, const Status& status, void* tag) = 0; }; +/// Async server-side API for doing bidirectional streaming RPCs, +/// where the incoming message stream coming from the client has messages of type \a R, +/// and the outgoing message stream coming from the server has messages of type \a W. template class ServerAsyncReaderWriter final : public ServerAsyncReaderWriterInterface { @@ -630,6 +865,16 @@ class ServerAsyncReaderWriter final explicit ServerAsyncReaderWriter(ServerContext* ctx) : call_(nullptr, nullptr, nullptr), ctx_(ctx) {} + /// Request notification of the sending the initial metadata to the client. Completion + /// will be notified by \a tag on the associated completion queue. + /// This call is optional, but if it is used, it cannot be used concurrently + /// with or after the \a Finish method. + /// + /// Implicit input parameter: + /// - The initial metadata that will be sent to the client from this op will be + /// taken from the \a ServerContext associated with the call. + /// + /// \param[in] tag Tag identifying this request. void SendInitialMetadata(void* tag) override { GPR_CODEGEN_ASSERT(!ctx_->sent_initial_metadata_); @@ -643,12 +888,14 @@ class ServerAsyncReaderWriter final call_.PerformOps(&meta_ops_); } + /// See the \a AsyncReaderInterface.Read method for semantics. void Read(R* msg, void* tag) override { read_ops_.set_output_tag(tag); read_ops_.RecvMessage(msg); call_.PerformOps(&read_ops_); } + /// See the \a AsyncWriterInterface.Write(const W& msg, void* tag) method for semantics. void Write(const W& msg, void* tag) override { write_ops_.set_output_tag(tag); EnsureInitialMetadataSent(&write_ops_); @@ -657,6 +904,7 @@ class ServerAsyncReaderWriter final call_.PerformOps(&write_ops_); } + /// See the \a AsyncWriterInterface.Write(const W& msg, WriteOptions options, void* tag) method for semantics. void Write(const W& msg, WriteOptions options, void* tag) override { write_ops_.set_output_tag(tag); if (options.is_last_message()) { @@ -667,6 +915,13 @@ class ServerAsyncReaderWriter final call_.PerformOps(&write_ops_); } + /// See the \a ServerAsyncReaderWriterInterface.WriteAndFinish method for semantics. + /// + /// Implicit input parameter: + /// - the \a ServerContext associated with this call is used + /// for sending trailing (and initial) metadata to the client. + /// + /// Note: \a status must have an OK code. void WriteAndFinish(const W& msg, WriteOptions options, const Status& status, void* tag) override { write_ops_.set_output_tag(tag); @@ -677,6 +932,13 @@ class ServerAsyncReaderWriter final call_.PerformOps(&write_ops_); } + /// See the \a ServerAsyncReaderWriterInterface.Finish method for semantics. + /// + /// Implicit input parameter: + /// - the \a ServerContext associated with this call is used + /// for sending trailing (and initial if not already sent) metadata to the client. + /// + /// Note: there are no restrictions are the code of \a status, it may be non-OK void Finish(const Status& status, void* tag) override { finish_ops_.set_output_tag(tag); EnsureInitialMetadataSent(&finish_ops_); diff --git a/include/grpc++/impl/codegen/async_unary_call.h b/include/grpc++/impl/codegen/async_unary_call.h index ea2da421984..15179e53d6e 100644 --- a/include/grpc++/impl/codegen/async_unary_call.h +++ b/include/grpc++/impl/codegen/async_unary_call.h @@ -55,10 +55,17 @@ class ClientAsyncResponseReaderInterface { virtual void Finish(R* msg, Status* status, void* tag) = 0; }; +/// Async API for client-side unary RPCs, where the message response +/// received from the server is of type \a R. template class ClientAsyncResponseReader final : public ClientAsyncResponseReaderInterface { public: + /// Start a call and write the request out. + /// \a tag will be notified on \a cq when the call has been started (i.e. + /// intitial metadata sent) and \a request has been written out. + /// Note that \a context will be used to fill in custom initial metadata + /// used to send to the server when starting the call. template static ClientAsyncResponseReader* Create(ChannelInterface* channel, CompletionQueue* cq, @@ -71,11 +78,24 @@ class ClientAsyncResponseReader final ClientAsyncResponseReader(call, context, request); } - /// always allocated against a call arena, no memory free required + // always allocated against a call arena, no memory free required static void operator delete(void* ptr, std::size_t size) { assert(size == sizeof(ClientAsyncResponseReader)); } + /// Request notification of the reading of initial metadata. Completion + /// will be notified by \a tag on the associated completion queue. + /// This call is optional, but if it is used, it cannot be used concurrently + /// with or after the \a Finish method. + /// + /// Once a completion has been notified, the initial metadata read from + /// the server will be accessable through the \a ClientContext used to + /// construct this object. + /// + /// \param[in] tag Tag identifying this request. + /// Side effect: + /// - the \a ClientContext associated with this call is updated with + /// possible initial and trailing metadata sent from the serve. void ReadInitialMetadata(void* tag) { GPR_CODEGEN_ASSERT(!context_->initial_metadata_received_); @@ -84,6 +104,24 @@ class ClientAsyncResponseReader final call_.PerformOps(&meta_buf_); } + /// Request to receive the server's response \a msg and final \a status for + /// the call, and to notify \a tag on this call's completion queue when + /// finished. + /// + /// This function will return when either: + /// - when the server's response message and status have been received. + /// - when the server has returned a non-OK status (no message expected in + /// this case). + /// - when the call failed for some reason and the library generated a + /// non-OK status. + /// + /// \param[in] tag Tag identifying this request. + /// \param[out] status To be updated with the operation status. + /// \param[out] msg To be filled in with the server's response message. + /// + /// Side effect: + /// - the \a ClientContext associated with this call is updated with + /// possible initial and trailing metadata sent from the server. void Finish(R* msg, Status* status, void* tag) { finish_buf_.set_output_tag(tag); if (!context_->initial_metadata_received_) { @@ -123,12 +161,23 @@ class ClientAsyncResponseReader final finish_buf_; }; +/// Async server-side API for handling unary calls, where the single +/// response message sent to the client is of type \a W. template class ServerAsyncResponseWriter final : public ServerAsyncStreamingInterface { public: explicit ServerAsyncResponseWriter(ServerContext* ctx) : call_(nullptr, nullptr, nullptr), ctx_(ctx) {} + /// Request notification of the sending the initial metadata to the client. Completion + /// will be notified by \a tag on the associated completion queue. + /// This call is optional, but if it is used, it cannot be used concurrently + /// with or after the \a Finish method. + /// + /// The initial metadata that will be sent to the client from this op will be + /// taken from the \a ServerContext associated with the call. + /// + /// \param[in] tag Tag identifying this request. void SendInitialMetadata(void* tag) override { GPR_CODEGEN_ASSERT(!ctx_->sent_initial_metadata_); @@ -142,6 +191,21 @@ class ServerAsyncResponseWriter final : public ServerAsyncStreamingInterface { call_.PerformOps(&meta_buf_); } + /// Indicate that the stream is to be finished and request notification + /// when the server has sent the appropriate signals to the client to + /// end the call. + /// Should not be used concurrently with other operations. + /// + /// \param[in] tag Tag identifying this request. + /// \param[in] status To be sent to the client as the result of the call. + /// \param[in] msg Message to be sent to the client. + /// Side effect: + /// - also sends initial metadata if not already sent (using the + /// \a ServerContext associated with this call). + /// + /// Note: if \a status has a non-OK code, then \a msg will not be sent, + /// and the client will receive only the status with possible trailing + /// metadata. void Finish(const W& msg, const Status& status, void* tag) { finish_buf_.set_output_tag(tag); if (!ctx_->sent_initial_metadata_) { @@ -162,6 +226,17 @@ class ServerAsyncResponseWriter final : public ServerAsyncStreamingInterface { call_.PerformOps(&finish_buf_); } + /// Indicate that the stream is to be finished with a non-OK status, + /// and request notification for when the server has finished sending the + /// appropriate signals to the client to end the call. + /// Should not be used concurrently with other operations. + /// + /// \param[in] tag Tag identifying this request. + /// \param[in] status To be sent to the client as the result of the call. + /// - Note: \a status must have a non-OK code. + /// Side effect: + /// - also sends initial metadata if not already sent (using the + /// \a ServerContext associated with this call). void FinishWithError(const Status& status, void* tag) { GPR_CODEGEN_ASSERT(!status.ok()); finish_buf_.set_output_tag(tag); diff --git a/include/grpc++/impl/codegen/call_hook.h b/include/grpc++/impl/codegen/call_hook.h index 812c4a91e70..85a5f86ab7b 100644 --- a/include/grpc++/impl/codegen/call_hook.h +++ b/include/grpc++/impl/codegen/call_hook.h @@ -39,8 +39,8 @@ namespace grpc { class CallOpSetInterface; class Call; -/// An interface that Channel and Server implement to allow them to hook -/// performing ops +/// This is an interface that Channel and Server implement to allow them to hook +/// performing ops. class CallHook { public: virtual ~CallHook() {} diff --git a/include/grpc++/impl/codegen/client_context.h b/include/grpc++/impl/codegen/client_context.h index c17ce201867..31bd0d258a6 100644 --- a/include/grpc++/impl/codegen/client_context.h +++ b/include/grpc++/impl/codegen/client_context.h @@ -151,7 +151,20 @@ namespace testing { class InteropClientContextInspector; } // namespace testing -/// Gives access to client side RPC configuration. +/// A ClientContext allows the person implementing a service client to: +/// +/// - Add custom metadata key-value pairs that will propagated to the server +/// side. +/// - Control call settings such as compression and authentication. +/// - Initial and trailing metadata coming from the server. +/// - Get performance metrics (ie, census). +/// +/// Context settings are only relevant to the call they are invoked with, that +/// is to say, they aren't sticky. Some of these settings, such as the +/// compression options, can be made persistant at channel construction time +/// (see \a grpc::CreateCustomChannel). +/// +/// \warning ClientContext instances should \em not be reused across rpcs. class ClientContext { public: ClientContext(); @@ -223,13 +236,24 @@ class ClientContext { deadline_ = deadline_tp.raw_time(); } - /// EXPERIMENTAL: Set this request to be idempotent + /// EXPERIMENTAL: Indicate that this request is idempotent. + /// By default, RPCs are assumed to not be idempotent. + /// + /// If true, the gRPC library assumes that it's safe to initiate + /// this RPC multiple times. void set_idempotent(bool idempotent) { idempotent_ = idempotent; } /// EXPERIMENTAL: Set this request to be cacheable + /// If set, grpc is free the GET verb for sending the request, + /// with the possibility of receiving a cached respone. void set_cacheable(bool cacheable) { cacheable_ = cacheable; } /// EXPERIMENTAL: Trigger wait-for-ready or not on this request + /// See grpc/doc/wait-for-ready.md. + /// If set, if an RPC made when a channel's connectivity state is + /// TRANSIENT_FAILURE or CONNECTING, the call will not "fail fast", + /// and the channel will wait until the channel is READY before making the + /// call. void set_wait_for_ready(bool wait_for_ready) { wait_for_ready_ = wait_for_ready; wait_for_ready_explicitly_set_ = true; diff --git a/include/grpc++/impl/codegen/server_context.h b/include/grpc++/impl/codegen/server_context.h index 07e3710b4bc..beaad1c6fa1 100644 --- a/include/grpc++/impl/codegen/server_context.h +++ b/include/grpc++/impl/codegen/server_context.h @@ -91,63 +91,129 @@ class InteropServerContextInspector; class ServerContextTestSpouse; } // namespace testing -/// Interface of server side rpc context. +/// A ServerContext allows the person implementing a service handler to: +/// +/// - Add custom initial and trailing metadata key-value pairs that will propagated +/// to the client side. +/// - Control call settings such as compression and authentication. +/// - Access Initial metadata coming from the client. +/// - Get performance metrics (ie, census). +/// +/// Context settings are only relevant to the call handler they are supplied to, that +/// is to say, they aren't sticky across multiple calls. Some of these settings, +/// such as the compression options, can be made persistant at server construction time +/// by specifying the approriate \a ChannelArguments parameter to the see \a grpc::Server +/// constructor. +/// +/// \warning ServerContext instances should \em not be reused across rpcs. class ServerContext { public: ServerContext(); // for async calls ~ServerContext(); + /// Return the deadline for the server call. std::chrono::system_clock::time_point deadline() const { return Timespec2Timepoint(deadline_); } + /// Return a \a gpr_timespec representation of the server call's deadline. gpr_timespec raw_deadline() const { return deadline_; } + /// Add the (\a meta_key, \a meta_value) pair to the initial metadata associated with + /// a server call. These are made available at the client side by the \a + /// grpc::ClientContext::GetServerInitialMetadata() method. + /// + /// \warning This method should only be called before sending initial metadata + /// to the client (which can happen explicitly, or implicitly when sending a + /// a response message or status to the client). + /// + /// \param meta_key The metadata key. If \a meta_value is binary data, it must + /// end in "-bin". + /// \param meta_value The metadata value. If its value is binary, it must be + /// base64-encoding (see https://tools.ietf.org/html/rfc4648#section-4) and \a + /// meta_key must end in "-bin". void AddInitialMetadata(const grpc::string& key, const grpc::string& value); + + /// Add the (\a meta_key, \a meta_value) pair to the initial metadata associated with + /// a server call. These are made available at the client side by the \a + /// grpc::ClientContext::GetServerTrailingMetadata() method. + /// + /// \warning This method should only be called before sending trailing metadata + /// to the client (which happens when the call is finished and a status is + /// sent to the client). + /// + /// \param meta_key The metadata key. If \a meta_value is binary data, it must + /// end in "-bin". + /// \param meta_value The metadata value. If its value is binary, it must be + /// base64-encoding (see https://tools.ietf.org/html/rfc4648#section-4) and \a + /// meta_key must end in "-bin". void AddTrailingMetadata(const grpc::string& key, const grpc::string& value); - /// IsCancelled is always safe to call when using sync API + /// IsCancelled is always safe to call when using sync API. /// When using async API, it is only safe to call IsCancelled after - /// the AsyncNotifyWhenDone tag has been delivered + /// the AsyncNotifyWhenDone tag has been delivered. bool IsCancelled() const; - // Cancel the Call from the server. This is a best-effort API and depending on - // when it is called, the RPC may still appear successful to the client. - // For example, if TryCancel() is called on a separate thread, it might race - // with the server handler which might return success to the client before - // TryCancel() was even started by the thread. - // - // It is the caller's responsibility to prevent such races and ensure that if - // TryCancel() is called, the serverhandler must return Status::CANCELLED. The - // only exception is that if the serverhandler is already returning an error - // status code, it is ok to not return Status::CANCELLED even if TryCancel() - // was called. + /// Cancel the Call from the server. This is a best-effort API and depending on + /// when it is called, the RPC may still appear successful to the client. + /// For example, if TryCancel() is called on a separate thread, it might race + /// with the server handler which might return success to the client before + /// TryCancel() was even started by the thread. + /// + /// It is the caller's responsibility to prevent such races and ensure that if + /// TryCancel() is called, the serverhandler must return Status::CANCELLED. The + /// only exception is that if the serverhandler is already returning an error + /// status code, it is ok to not return Status::CANCELLED even if TryCancel() + /// was called. void TryCancel() const; + /// Return a collection of initial metadata key-value pairs sent from the + /// client. Note that keys + /// may happen more than once (ie, a \a std::multimap is returned). + /// + /// It is safe to use this method after initial metadata has been received, + /// Calls always begin with the client sending initial metadata, so this is + /// safe to access as soon as the call has begun on the server side. + /// + /// \return A multimap of initial metadata key-value pairs from the server. const std::multimap& client_metadata() const { return *client_metadata_.map(); } + /// Return the compression algorithm to be used by the server call. grpc_compression_level compression_level() const { return compression_level_; } + /// Set \a algorithm to be the compression algorithm used for the server call. + /// + /// \param algorithm The compression algorithm used for the server call. void set_compression_level(grpc_compression_level level) { compression_level_set_ = true; compression_level_ = level; } + /// Return a bool indicating whether the compression level for this call + /// has been set (either implicitly or through a previous call to + /// \a set_compression_level bool compression_level_set() const { return compression_level_set_; } + /// Return the compression algorithm to be used by the server call. grpc_compression_algorithm compression_algorithm() const { return compression_algorithm_; } + /// Set \a algorithm to be the compression algorithm used for the server call. + /// + /// \param algorithm The compression algorithm used for the server call. void set_compression_algorithm(grpc_compression_algorithm algorithm); - // Set the load reporting costs in \a cost_data for the call. + /// Set the load reporting costs in \a cost_data for the call. void SetLoadReportingCosts(const std::vector& cost_data); + /// Return the authentication context for this server call. + /// + /// \see grpc::AuthContext. std::shared_ptr auth_context() const { if (auth_context_.get() == nullptr) { auth_context_ = CreateAuthContext(call_); @@ -155,24 +221,25 @@ class ServerContext { return auth_context_; } - // Return the peer uri in a string. - // WARNING: this value is never authenticated or subject to any security - // related code. It must not be used for any authentication related - // functionality. Instead, use auth_context. + /// Return the peer uri in a string. + /// WARNING: this value is never authenticated or subject to any security + /// related code. It must not be used for any authentication related + /// functionality. Instead, use auth_context. grpc::string peer() const; + /// Get the census context associated with this server call. const struct census_context* census_context() const; - // Async only. Has to be called before the rpc starts. - // Returns the tag in completion queue when the rpc finishes. - // IsCancelled() can then be called to check whether the rpc was cancelled. + /// Async only. Has to be called before the rpc starts. + /// Returns the tag in completion queue when the rpc finishes. + /// IsCancelled() can then be called to check whether the rpc was cancelled. void AsyncNotifyWhenDone(void* tag) { has_notify_when_done_tag_ = true; async_notify_when_done_tag_ = tag; } - // Should be used for framework-level extensions only. - // Applications never need to call this method. + /// Should be used for framework-level extensions only. + /// Applications never need to call this method. grpc_call* c_call() { return call_; } private: @@ -205,14 +272,14 @@ class ServerContext { friend class UnknownMethodHandler; friend class ::grpc::ClientContext; - // Prevent copying. + /// Prevent copying. ServerContext(const ServerContext&); ServerContext& operator=(const ServerContext&); class CompletionOp; void BeginCompletionOp(Call* call); - // Return the tag queued by BeginCompletionOp() + /// Return the tag queued by BeginCompletionOp() CompletionQueueTag* GetCompletionOpTag(); ServerContext(gpr_timespec deadline, grpc_metadata_array* arr); diff --git a/include/grpc++/impl/codegen/status_code_enum.h b/include/grpc++/impl/codegen/status_code_enum.h index 2eb97e83c11..a60cdef60e8 100644 --- a/include/grpc++/impl/codegen/status_code_enum.h +++ b/include/grpc++/impl/codegen/status_code_enum.h @@ -141,7 +141,6 @@ enum StatusCode { /// anything. So in general it is unsafe to retry on this status code /// if the call is non-idempotent. /// - /// /// See litmus test above for deciding between FAILED_PRECONDITION, ABORTED, /// and UNAVAILABLE. UNAVAILABLE = 14, diff --git a/include/grpc++/impl/codegen/sync_stream.h b/include/grpc++/impl/codegen/sync_stream.h index 34b814e9e39..ecde15fac9f 100644 --- a/include/grpc++/impl/codegen/sync_stream.h +++ b/include/grpc++/impl/codegen/sync_stream.h @@ -50,16 +50,28 @@ class ClientStreamingInterface { public: virtual ~ClientStreamingInterface() {} - /// Wait until the stream finishes, and return the final status. When the - /// client side declares it has no more message to send, either implicitly or - /// by calling \a WritesDone(), it needs to make sure there is no more message - /// to be received from the server, either implicitly or by getting a false - /// from a \a Read(). + /// Block waiting until the stream finishes and a final status of the call is + /// available. + /// + /// It is appropriate to call this method when both: + /// * the calling code (client-side) has no more message to send (this can be declared implicitly + /// by calling this method, or explicitly through an earlier call to \a + /// WritesDone. + /// * there are no more messages to be received from the server (which can + /// be known implicitly, or explicitly from an earlier call to \a Read that + /// returned "false" /// /// This function will return either: /// - when all incoming messages have been read and the server has returned /// status. - /// - OR when the server has returned a non-OK status. + /// - when the server has returned a non-OK status. + /// - OR when the call failed for some reason and the library generated a + /// status. + /// + /// Return values: + /// - \a Status contains the status code, message and details for the call + /// - the \a ClientContext associated with this call is updated with + /// possible trailing metadata sent from the server. virtual Status Finish() = 0; }; @@ -68,7 +80,12 @@ class ServerStreamingInterface { public: virtual ~ServerStreamingInterface() {} - /// Blocking send initial metadata to client. + /// Block to send initial metadata to client. + /// This call is optional, but if it is used, it cannot be used concurrently + /// with or after the \a Finish method. + /// + /// The initial metadata that will be sent to the client will be + /// taken from the \a ServerContext associated with the call. virtual void SendInitialMetadata() = 0; }; @@ -78,10 +95,10 @@ class ReaderInterface { public: virtual ~ReaderInterface() {} - /// Upper bound on the next message size available for reading on this stream + /// Get an upper bound on the next message size available for reading on this stream. virtual bool NextMessageSize(uint32_t* sz) = 0; - /// Blocking read a message and parse to \a msg. Returns \a true on success. + /// Block to read a message and parse to \a msg. Returns \a true on success. /// This is thread-safe with respect to \a Write or \WritesDone methods on /// the same stream. It should not be called concurrently with another \a /// Read on the same stream as the order of delivery will not be defined. @@ -100,7 +117,7 @@ class WriterInterface { public: virtual ~WriterInterface() {} - /// Blocking write \a msg to the stream with WriteOptions \a options. + /// Block to write \a msg to the stream with WriteOptions \a options. /// This is thread-safe with respect to \a Read /// /// \param msg The message to be written to the stream. @@ -109,7 +126,7 @@ class WriterInterface { /// \return \a true on success, \a false when the stream has been closed. virtual bool Write(const W& msg, WriteOptions options) = 0; - /// Blocking write \a msg to the stream with default write options. + /// Block to write \a msg to the stream with default write options. /// This is thread-safe with respect to \a Read /// /// \param msg The message to be written to the stream. @@ -141,17 +158,21 @@ template class ClientReaderInterface : public ClientStreamingInterface, public ReaderInterface { public: - /// Blocking wait for initial metadata from server. The received metadata + /// Block to wait for initial metadata from server. The received metadata /// can only be accessed after this call returns. Should only be called before /// the first read. Calling this method is optional, and if it is not called /// the metadata will be available in ClientContext after the first read. virtual void WaitForInitialMetadata() = 0; }; +/// Synchronous (blocking) client-side API for doing server-streaming RPCs, where the +/// stream of messages coming from the server has messages of type \a R. template class ClientReader final : public ClientReaderInterface { public: - /// Blocking create a stream and write the first request out. + /// Block to create a stream and write the initial metadata and \a request out. + /// Note that \a context will be used to fill in custom initial metadata + /// used to send to the server when starting the call. template ClientReader(ChannelInterface* channel, const RpcMethod& method, ClientContext* context, const W& request) @@ -172,6 +193,13 @@ class ClientReader final : public ClientReaderInterface { cq_.Pluck(&ops); } + /// See the \a ClientStreamingInterface.WaitForInitialMetadata method for + /// semantics. + /// + // Side effect: + /// Once complete, the initial metadata read from + /// the server will be accessable through the \a ClientContext used to + /// construct this object. void WaitForInitialMetadata() override { GPR_CODEGEN_ASSERT(!context_->initial_metadata_received_); @@ -181,11 +209,17 @@ class ClientReader final : public ClientReaderInterface { cq_.Pluck(&ops); /// status ignored } + /// See the \a ReaderInterface.NextMessageSize for semantics. bool NextMessageSize(uint32_t* sz) override { *sz = call_.max_receive_message_size(); return true; } + /// See the \a ReaderInterface.Read method for semantics. + /// Side effect: + /// this also receives initial metadata from the server, if not + /// already received (if initial metadata is received, it can be then accessed + /// through the \a ClientContext associated with this call). bool Read(R* msg) override { CallOpSet> ops; if (!context_->initial_metadata_received_) { @@ -196,6 +230,11 @@ class ClientReader final : public ClientReaderInterface { return cq_.Pluck(&ops) && ops.got_message; } + /// See the \a ClientStreamingInterface.Finish method for semantics. + /// + /// Side effect: + /// - the \a ClientContext associated with this call is updated with + /// possible metadata received from the server. Status Finish() override { CallOpSet ops; Status status; @@ -211,23 +250,30 @@ class ClientReader final : public ClientReaderInterface { Call call_; }; -/// Client-side interface for streaming writes of message of type \a W. +/// Client-side interface for streaming writes of message type \a W. template class ClientWriterInterface : public ClientStreamingInterface, public WriterInterface { public: - /// Half close writing from the client. - /// Block until currently-pending writes are completed. + /// Half close writing from the client. (signal that the stream of messages + /// coming from the clinet is complete). + /// Blocks until currently-pending writes are completed. /// Thread safe with respect to \a Read operations only /// /// \return Whether the writes were successful. virtual bool WritesDone() = 0; }; +/// Synchronous (blocking) client-side API for doing client-streaming RPCs, +/// where the outgoing message stream coming from the client has messages of type \a W. template class ClientWriter : public ClientWriterInterface { public: - /// Blocking create a stream. + /// Block to create a stream (i.e. send request headers and other initial metadata to the server). + /// Note that \a context will be used to fill in custom initial metadata. + /// \a response will be filled in with the single expected response + /// message from the server upon a successful call to the \a Finish + /// method of this instance. template ClientWriter(ChannelInterface* channel, const RpcMethod& method, ClientContext* context, R* response) @@ -248,6 +294,13 @@ class ClientWriter : public ClientWriterInterface { } } + /// See the \a ClientStreamingInterface.WaitForInitialMetadata method for + /// semantics. + /// + // Side effect: + /// Once complete, the initial metadata read from + /// the server will be accessable through the \a ClientContext used to + /// construct this object. void WaitForInitialMetadata() { GPR_CODEGEN_ASSERT(!context_->initial_metadata_received_); @@ -257,6 +310,12 @@ class ClientWriter : public ClientWriterInterface { cq_.Pluck(&ops); // status ignored } + /// See the WriterInterface.Write(const W& msg, WriteOptions options) method + /// for semantics. + /// + /// Side effect: + /// Also sends initial metadata if not already sent (using the \a ClientContext + /// associated with this call). using WriterInterface::Write; bool Write(const W& msg, WriteOptions options) override { CallOpSet { return cq_.Pluck(&ops); } + /// See the \a ClientWriterInterface.WritesDone method for semantics. bool WritesDone() override { CallOpSet ops; ops.ClientSendClose(); @@ -287,7 +347,11 @@ class ClientWriter : public ClientWriterInterface { return cq_.Pluck(&ops); } - /// Read the final response and wait for the final status. + /// See the ClientStreamingInterface.Finish method for semantics. + /// Side effects: + /// - Also receives initial metadata if not already received. + /// - Attempts to fill in the \a response parameter passed to the constructor + /// of this instance with the response message from the server. Status Finish() override { Status status; if (!context_->initial_metadata_received_) { @@ -308,29 +372,39 @@ class ClientWriter : public ClientWriterInterface { Call call_; }; -/// Client-side interface for bi-directional streaming. +/// Client-side interface for bi-directional streaming with +/// client-to-server stream messages of type \a W and +/// server-to-client stream messages of type \a R. template class ClientReaderWriterInterface : public ClientStreamingInterface, public WriterInterface, public ReaderInterface { public: - /// Blocking wait for initial metadata from server. The received metadata + /// Block to wait for initial metadata from server. The received metadata /// can only be accessed after this call returns. Should only be called before /// the first read. Calling this method is optional, and if it is not called /// the metadata will be available in ClientContext after the first read. virtual void WaitForInitialMetadata() = 0; - /// Block until currently-pending writes are completed. + /// Half close writing from the client. (signal that the stream of messages + /// coming from the clinet is complete). + /// Blocks until currently-pending writes are completed. /// Thread-safe with respect to \a Read /// /// \return Whether the writes were successful. virtual bool WritesDone() = 0; }; +/// Synchronous (blocking) client-side API for bi-directional streaming RPCs, where the +/// outgoing message stream coming from the client has messages of type \a W, +/// and the incoming messages stream coming from the server has messages of type +/// \a R. template class ClientReaderWriter final : public ClientReaderWriterInterface { public: - /// Blocking create a stream. + /// Block to create a stream and write the initial metadata and \a request out. + /// Note that \a context will be used to fill in custom initial metadata + /// used to send to the server when starting the call. ClientReaderWriter(ChannelInterface* channel, const RpcMethod& method, ClientContext* context) : context_(context), @@ -347,6 +421,13 @@ class ClientReaderWriter final : public ClientReaderWriterInterface { } } + /// Block waiting to read initial metadata from the server. + /// This call is optional, but if it is used, it cannot be used concurrently + /// with or after the \a Finish method. + /// + /// Once complete, the initial metadata read from + /// the server will be accessable through the \a ClientContext used to + /// construct this object. void WaitForInitialMetadata() override { GPR_CODEGEN_ASSERT(!context_->initial_metadata_received_); @@ -361,6 +442,10 @@ class ClientReaderWriter final : public ClientReaderWriterInterface { return true; } + /// See the \a ReaderInterface.Read method for semantics. + /// Side effect: + /// Also receives initial metadata if not already received (updates the \a + /// ClientContext associated with this call in that case). bool Read(R* msg) override { CallOpSet> ops; if (!context_->initial_metadata_received_) { @@ -371,6 +456,11 @@ class ClientReaderWriter final : public ClientReaderWriterInterface { return cq_.Pluck(&ops) && ops.got_message; } + /// See the \a WriterInterface.Write method for semantics. + /// + /// Side effect: + /// Also sends initial metadata if not already sent (using the + /// \a ClientContext associated with this call to fill in values). using WriterInterface::Write; bool Write(const W& msg, WriteOptions options) override { CallOpSet { return cq_.Pluck(&ops); } + /// See the ClientWriterInterface.WritesDone method for semantics. bool WritesDone() override { CallOpSet ops; ops.ClientSendClose(); @@ -401,6 +492,11 @@ class ClientReaderWriter final : public ClientReaderWriterInterface { return cq_.Pluck(&ops); } + /// See the ClientStreamingInterface.Finish method for semantics. + /// + /// Side effect: + /// - the \a ClientContext associated with this call is updated with + /// possible trailing metadata sent from the server. Status Finish() override { CallOpSet ops; if (!context_->initial_metadata_received_) { @@ -424,11 +520,18 @@ template class ServerReaderInterface : public ServerStreamingInterface, public ReaderInterface {}; +/// Synchronous (blocking) server-side API for doing client-streaming RPCs, +/// where the incoming message stream coming from the client has messages of +/// type \a R. template class ServerReader final : public ServerReaderInterface { public: ServerReader(Call* call, ServerContext* ctx) : call_(call), ctx_(ctx) {} + /// See the \a ServerStreamingInterface.SendInitialMetadata method + /// for semantics. + /// Note that initial metadata will be affected by the + /// \a ServerContext associated with this call. void SendInitialMetadata() override { GPR_CODEGEN_ASSERT(!ctx_->sent_initial_metadata_); @@ -443,11 +546,13 @@ class ServerReader final : public ServerReaderInterface { call_->cq()->Pluck(&ops); } + /// See the \a ReaderInterface.NextMessageSize method. bool NextMessageSize(uint32_t* sz) override { *sz = call_->max_receive_message_size(); return true; } + /// See the \a ReaderInterface.Read method for semantics. bool Read(R* msg) override { CallOpSet> ops; ops.RecvMessage(msg); @@ -465,11 +570,18 @@ template class ServerWriterInterface : public ServerStreamingInterface, public WriterInterface {}; +/// Synchronous (blocking) server-side API for doing for doing a +/// server-streaming RPCs, where the outgoing message stream coming from the +/// server has messages of type \a W. template class ServerWriter final : public ServerWriterInterface { public: ServerWriter(Call* call, ServerContext* ctx) : call_(call), ctx_(ctx) {} + /// See the \a ServerStreamingInterface.SendInitialMetadata method + /// for semantics. + /// Note that initial metadata will be affected by the + /// \a ServerContext associated with this call. void SendInitialMetadata() override { GPR_CODEGEN_ASSERT(!ctx_->sent_initial_metadata_); @@ -484,6 +596,11 @@ class ServerWriter final : public ServerWriterInterface { call_->cq()->Pluck(&ops); } + /// See the \a WriterInterface.Write method for semantics. + /// + /// Side effect: + /// Also sends initial metadata if not already sent (using the + /// \a ClientContext associated with this call to fill in values). using WriterInterface::Write; bool Write(const W& msg, WriteOptions options) override { if (options.is_last_message()) { @@ -576,20 +693,32 @@ class ServerReaderWriterBody final { }; } // namespace internal -/// class to represent the user API for a bidirectional streaming call +/// Synchronous (blocking) server-side API for a bidirectional +/// streaming call, where the incoming message stream coming from the client has messages of +/// type \a R, and the outgoing message streaming coming from the server has messages of type \a W. template class ServerReaderWriter final : public ServerReaderWriterInterface { public: ServerReaderWriter(Call* call, ServerContext* ctx) : body_(call, ctx) {} + /// See the \a ServerStreamingInterface.SendInitialMetadata method + /// for semantics. + /// Note that initial metadata will be affected by the + /// \a ServerContext associated with this call. void SendInitialMetadata() override { body_.SendInitialMetadata(); } + /// See the \a ReaderInterface.NextMessageSize method for semantics bool NextMessageSize(uint32_t* sz) override { return body_.NextMessageSize(sz); } + /// See the \a ReaderInterface.Read method for semantics bool Read(R* msg) override { return body_.Read(msg); } + /// See the \a WriterInterface.Write(const W& msg, WriteOptions options) method for semantics. + /// Side effect: + /// Also sends initial metadata if not already sent (using the \a + /// ServerContext associated with this call). using WriterInterface::Write; bool Write(const W& msg, WriteOptions options) override { return body_.Write(msg, options); @@ -615,12 +744,27 @@ class ServerUnaryStreamer final ServerUnaryStreamer(Call* call, ServerContext* ctx) : body_(call, ctx), read_done_(false), write_done_(false) {} + /// Block to send initial metadata to client. + /// Implicit input parameter: + /// - the \a ServerContext associated with this call will be used for + /// sending initial metadata. void SendInitialMetadata() override { body_.SendInitialMetadata(); } + /// Get an upper bound on the request message size from the client. bool NextMessageSize(uint32_t* sz) override { return body_.NextMessageSize(sz); } + /// Read a message of type \a R into \a msg. Completion will be notified by \a + /// tag on the associated completion queue. + /// This is thread-safe with respect to \a Write or \a WritesDone methods. It + /// should not be called concurrently with other streaming APIs + /// on the same stream. It is not meaningful to call it concurrently + /// with another \a Read on the same stream since reads on the same stream + /// are delivered in order. + /// + /// \param[out] msg Where to eventually store the read message. + /// \param[in] tag The tag identifying the operation. bool Read(RequestType* request) override { if (read_done_) { return false; @@ -629,6 +773,13 @@ class ServerUnaryStreamer final return body_.Read(request); } + /// Block to write \a msg to the stream with WriteOptions \a options. + /// This is thread-safe with respect to \a Read + /// + /// \param msg The message to be written to the stream. + /// \param options The WriteOptions affecting the write operation. + /// + /// \return \a true on success, \a false when the stream has been closed. using WriterInterface::Write; bool Write(const ResponseType& response, WriteOptions options) override { if (write_done_ || !read_done_) { @@ -656,12 +807,27 @@ class ServerSplitStreamer final ServerSplitStreamer(Call* call, ServerContext* ctx) : body_(call, ctx), read_done_(false) {} + /// Block to send initial metadata to client. + /// Implicit input parameter: + /// - the \a ServerContext associated with this call will be used for + /// sending initial metadata. void SendInitialMetadata() override { body_.SendInitialMetadata(); } + /// Get an upper bound on the request message size from the client. bool NextMessageSize(uint32_t* sz) override { return body_.NextMessageSize(sz); } + /// Read a message of type \a R into \a msg. Completion will be notified by \a + /// tag on the associated completion queue. + /// This is thread-safe with respect to \a Write or \a WritesDone methods. It + /// should not be called concurrently with other streaming APIs + /// on the same stream. It is not meaningful to call it concurrently + /// with another \a Read on the same stream since reads on the same stream + /// are delivered in order. + /// + /// \param[out] msg Where to eventually store the read message. + /// \param[in] tag The tag identifying the operation. bool Read(RequestType* request) override { if (read_done_) { return false; @@ -670,6 +836,13 @@ class ServerSplitStreamer final return body_.Read(request); } + /// Block to write \a msg to the stream with WriteOptions \a options. + /// This is thread-safe with respect to \a Read + /// + /// \param msg The message to be written to the stream. + /// \param options The WriteOptions affecting the write operation. + /// + /// \return \a true on success, \a false when the stream has been closed. using WriterInterface::Write; bool Write(const ResponseType& response, WriteOptions options) override { return read_done_ && body_.Write(response, options); diff --git a/include/grpc++/impl/server_builder_plugin.h b/include/grpc++/impl/server_builder_plugin.h index 76972328074..8ce16d66780 100644 --- a/include/grpc++/impl/server_builder_plugin.h +++ b/include/grpc++/impl/server_builder_plugin.h @@ -43,6 +43,10 @@ namespace grpc { class ServerInitializer; class ChannelArguments; +/// A builder class for the creation and startup of \a grpc::Server instances. +/// This is interface is meant for internal usage only. Implementations of this +/// interface should add themselves to a \a ServerBuilder instance through the +/// \a InternalAddPluginFactory method. class ServerBuilderPlugin { public: virtual ~ServerBuilderPlugin() {}