diff --git a/include/grpc++/client_context.h b/include/grpc++/client_context.h index f74de8fad4f..ab5965f55a9 100644 --- a/include/grpc++/client_context.h +++ b/include/grpc++/client_context.h @@ -47,9 +47,19 @@ using std::chrono::system_clock; struct grpc_call; struct grpc_completion_queue; +namespace google { +namespace protobuf { +class Message; +} // namespace protobuf +} // namespace google + namespace grpc { class CallOpBuffer; +class ChannelInterface; +class CompletionQueue; +class RpcMethod; +class Status; template class ClientReader; template class ClientWriter; template class ClientReaderWriter; @@ -65,6 +75,16 @@ class ClientContext { void AddMetadata(const grpc::string &meta_key, const grpc::string &meta_value); + std::multimap GetServerInitialMetadata() { + GPR_ASSERT(initial_metadata_received_); + return recv_initial_metadata_; + } + + std::multimap GetServerTrailingMetadata() { + // TODO(yangg) check finished + return trailing_metadata_; + } + void set_absolute_deadline(const system_clock::time_point &deadline); system_clock::time_point absolute_deadline(); @@ -83,6 +103,15 @@ class ClientContext { template friend class ::grpc::ClientAsyncReader; template friend class ::grpc::ClientAsyncWriter; template friend class ::grpc::ClientAsyncReaderWriter; + friend Status BlockingUnaryCall(ChannelInterface *channel, const RpcMethod &method, + ClientContext *context, + const google::protobuf::Message &request, + google::protobuf::Message *result); + friend void AsyncUnaryCall(ChannelInterface *channel, const RpcMethod &method, + ClientContext *context, + const google::protobuf::Message &request, + google::protobuf::Message *result, Status *status, + CompletionQueue *cq, void *tag); grpc_call *call() { return call_; } void set_call(grpc_call *call) { diff --git a/include/grpc++/completion_queue.h b/include/grpc++/completion_queue.h index 3e68cf37760..80874cd1e69 100644 --- a/include/grpc++/completion_queue.h +++ b/include/grpc++/completion_queue.h @@ -58,6 +58,7 @@ class Server; class CompletionQueueTag { public: + virtual ~CompletionQueueTag() {} // Called prior to returning from Next(), return value // is the status of the operation (return status is the default thing // to do) diff --git a/include/grpc++/impl/call.h b/include/grpc++/impl/call.h index 853f19e9b31..7aa22ee7c25 100644 --- a/include/grpc++/impl/call.h +++ b/include/grpc++/impl/call.h @@ -54,7 +54,7 @@ namespace grpc { class Call; -class CallOpBuffer final : public CompletionQueueTag { +class CallOpBuffer : public CompletionQueueTag { public: CallOpBuffer() : return_tag_(this) {} ~CallOpBuffer(); diff --git a/src/cpp/client/client_unary_call.cc b/src/cpp/client/client_unary_call.cc index 1221630a35c..69f0b77d7b8 100644 --- a/src/cpp/client/client_unary_call.cc +++ b/src/cpp/client/client_unary_call.cc @@ -34,6 +34,7 @@ #include #include #include +#include #include #include #include @@ -51,20 +52,39 @@ Status BlockingUnaryCall(ChannelInterface *channel, const RpcMethod &method, Status status; buf.AddSendInitialMetadata(context); buf.AddSendMessage(request); + buf.AddRecvInitialMetadata(&context->recv_initial_metadata_); bool got_message; buf.AddRecvMessage(result, &got_message); buf.AddClientSendClose(); - buf.AddClientRecvStatus(nullptr, &status); // TODO metadata + buf.AddClientRecvStatus(&context->trailing_metadata_, &status); call.PerformOps(&buf); GPR_ASSERT(cq.Pluck(&buf) && (got_message || !status.IsOk())); return status; } +class ClientAsyncRequest final : public CallOpBuffer { + public: + void FinalizeResult(void** tag, bool* status) override { + CallOpBuffer::FinalizeResult(tag, status); + delete this; + } +}; + void AsyncUnaryCall(ChannelInterface *channel, const RpcMethod &method, ClientContext *context, const google::protobuf::Message &request, google::protobuf::Message *result, Status *status, CompletionQueue *cq, void *tag) { - + ClientAsyncRequest* buf = new ClientAsyncRequest; + buf->Reset(tag); + Call call(channel->CreateCall(method, context, cq)); + buf->AddSendInitialMetadata(context); + buf->AddSendMessage(request); + buf->AddRecvInitialMetadata(&context->recv_initial_metadata_); + buf->AddRecvMessage(result, nullptr); + buf->AddClientSendClose(); + buf->AddClientRecvStatus(&context->trailing_metadata_, status); + call.PerformOps(buf); } + } // namespace grpc