From 6f7a98916bbd1ed21398eff30643665c6ec25e3a Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Tue, 20 Oct 2020 08:12:43 -0700 Subject: [PATCH] Reduce template use in server --- include/grpcpp/impl/codegen/byte_buffer.h | 10 ++- .../grpcpp/impl/codegen/completion_queue.h | 14 +++- include/grpcpp/impl/codegen/method_handler.h | 78 ++++++++++++------- include/grpcpp/impl/codegen/server_context.h | 14 +++- src/compiler/cpp_generator.cc | 4 +- 5 files changed, 80 insertions(+), 40 deletions(-) diff --git a/include/grpcpp/impl/codegen/byte_buffer.h b/include/grpcpp/impl/codegen/byte_buffer.h index 6e64ec9981e..a8836fd6888 100644 --- a/include/grpcpp/impl/codegen/byte_buffer.h +++ b/include/grpcpp/impl/codegen/byte_buffer.h @@ -40,8 +40,9 @@ template class CallbackUnaryHandler; template class CallbackServerStreamingHandler; -template -class RpcMethodHandler; +template +void* UnaryDeserializeHelper(grpc_call*, grpc_byte_buffer*, ::grpc::Status*, + RequestType*); template class ServerStreamingHandler; template <::grpc::StatusCode code> @@ -162,8 +163,9 @@ class ByteBuffer final { template friend class internal::CallOpRecvMessage; friend class internal::CallOpGenericRecvMessage; - template - friend class internal::RpcMethodHandler; + template + friend void* internal::UnaryDeserializeHelper(grpc_call*, grpc_byte_buffer*, + ::grpc::Status*, RequestType*); template friend class internal::ServerStreamingHandler; template diff --git a/include/grpcpp/impl/codegen/completion_queue.h b/include/grpcpp/impl/codegen/completion_queue.h index ca0c77276a8..2552272aa8d 100644 --- a/include/grpcpp/impl/codegen/completion_queue.h +++ b/include/grpcpp/impl/codegen/completion_queue.h @@ -38,6 +38,7 @@ #include #include #include +#include #include #include #include @@ -59,7 +60,12 @@ namespace internal { template class ServerReaderWriterBody; -template +template +void UnaryRunHandlerHelper( + const ::grpc::internal::MethodHandler::HandlerParameter&, ResponseType*, + ::grpc::Status&); +template class RpcMethodHandler; template class ClientStreamingHandler; @@ -265,8 +271,10 @@ class CompletionQueue : private ::grpc::GrpcLibraryCodegen { friend class ::grpc::ServerWriter; template friend class ::grpc::internal::ServerReaderWriterBody; - template - friend class ::grpc::internal::RpcMethodHandler; + template + friend void ::grpc::internal::UnaryRunHandlerHelper( + const ::grpc::internal::MethodHandler::HandlerParameter&, ResponseType*, + ::grpc::Status&); template friend class ::grpc::internal::ClientStreamingHandler; template diff --git a/include/grpcpp/impl/codegen/method_handler.h b/include/grpcpp/impl/codegen/method_handler.h index 0033936b04b..604de8905d0 100644 --- a/include/grpcpp/impl/codegen/method_handler.h +++ b/include/grpcpp/impl/codegen/method_handler.h @@ -49,8 +49,52 @@ template #endif // GRPC_ALLOW_EXCEPTIONS } +/// A helper function with reduced templating to do the common work needed to +/// actually send the server response. Uses non-const parameter for Status since +/// this should only ever be called from the end of the RunHandler method. + +template +void UnaryRunHandlerHelper(const MethodHandler::HandlerParameter& param, + ResponseType* rsp, ::grpc::Status& status) { + GPR_CODEGEN_ASSERT(!param.server_context->sent_initial_metadata_); + ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata, + ::grpc::internal::CallOpSendMessage, + ::grpc::internal::CallOpServerSendStatus> + ops; + ops.SendInitialMetadata(¶m.server_context->initial_metadata_, + param.server_context->initial_metadata_flags()); + if (param.server_context->compression_level_set()) { + ops.set_compression_level(param.server_context->compression_level()); + } + if (status.ok()) { + status = ops.SendMessagePtr(rsp); + } + ops.ServerSendStatus(¶m.server_context->trailing_metadata_, status); + param.call->PerformOps(&ops); + param.call->cq()->Pluck(&ops); +} + +/// A helper function with reduced templating to do deserializing. + +template +void* UnaryDeserializeHelper(grpc_call* call, grpc_byte_buffer* req, + ::grpc::Status* status, RequestType* request) { + ::grpc::ByteBuffer buf; + buf.set_buffer(req); + *status = ::grpc::SerializationTraits::Deserialize( + &buf, static_cast(request)); + buf.Release(); + if (status->ok()) { + return request; + } + request->~RequestType(); + return nullptr; +} + /// A wrapper class of an application provided rpc method handler. -template +template class RpcMethodHandler : public ::grpc::internal::MethodHandler { public: RpcMethodHandler( @@ -71,40 +115,16 @@ class RpcMethodHandler : public ::grpc::internal::MethodHandler { }); static_cast(param.request)->~RequestType(); } - - GPR_CODEGEN_ASSERT(!param.server_context->sent_initial_metadata_); - ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata, - ::grpc::internal::CallOpSendMessage, - ::grpc::internal::CallOpServerSendStatus> - ops; - ops.SendInitialMetadata(¶m.server_context->initial_metadata_, - param.server_context->initial_metadata_flags()); - if (param.server_context->compression_level_set()) { - ops.set_compression_level(param.server_context->compression_level()); - } - if (status.ok()) { - status = ops.SendMessagePtr(&rsp); - } - ops.ServerSendStatus(¶m.server_context->trailing_metadata_, status); - param.call->PerformOps(&ops); - param.call->cq()->Pluck(&ops); + UnaryRunHandlerHelper(param, static_cast(&rsp), status); } void* Deserialize(grpc_call* call, grpc_byte_buffer* req, ::grpc::Status* status, void** /*handler_data*/) final { - ::grpc::ByteBuffer buf; - buf.set_buffer(req); auto* request = new (::grpc::g_core_codegen_interface->grpc_call_arena_alloc( - call, sizeof(RequestType))) RequestType(); - *status = - ::grpc::SerializationTraits::Deserialize(&buf, request); - buf.Release(); - if (status->ok()) { - return request; - } - request->~RequestType(); - return nullptr; + call, sizeof(RequestType))) RequestType; + return UnaryDeserializeHelper(call, req, status, + static_cast(request)); } private: diff --git a/include/grpcpp/impl/codegen/server_context.h b/include/grpcpp/impl/codegen/server_context.h index a54a962b7fb..56dcb61eec2 100644 --- a/include/grpcpp/impl/codegen/server_context.h +++ b/include/grpcpp/impl/codegen/server_context.h @@ -37,6 +37,7 @@ #include #include #include +#include #include #include #include @@ -75,7 +76,11 @@ template class CallbackBidiHandler; template class ClientStreamingHandler; -template +template +void UnaryRunHandlerHelper(const MethodHandler::HandlerParameter&, + ResponseType*, Status&); +template class RpcMethodHandler; template class FinishOnlyReactor; @@ -355,7 +360,12 @@ class ServerContextBase { friend class ::grpc::ServerWriter; template friend class ::grpc::internal::ServerReaderWriterBody; - template + template + friend void ::grpc::internal::UnaryRunHandlerHelper( + const internal::MethodHandler::HandlerParameter& param, ResponseType* rsp, + Status& status); + template friend class ::grpc::internal::RpcMethodHandler; template friend class ::grpc::internal::ClientStreamingHandler; diff --git a/src/compiler/cpp_generator.cc b/src/compiler/cpp_generator.cc index df212784d82..270d60fdf49 100644 --- a/src/compiler/cpp_generator.cc +++ b/src/compiler/cpp_generator.cc @@ -2214,8 +2214,8 @@ void PrintSourceService(grpc_generator::Printer* printer, " $prefix$$Service$_method_names[$Idx$],\n" " ::grpc::internal::RpcMethod::NORMAL_RPC,\n" " new ::grpc::internal::RpcMethodHandler< $ns$$Service$::Service, " - "$Request$, " - "$Response$>(\n" + "$Request$, $Response$, ::grpc::protobuf::MessageLite, " + "::grpc::protobuf::MessageLite>(\n" " []($ns$$Service$::Service* service,\n" " ::grpc::ServerContext* ctx,\n" " const $Request$* req,\n"