From 80582c6d337be1ad7a8abf7f4a11ac6bf183b5be Mon Sep 17 00:00:00 2001 From: Dennis Hezel Date: Wed, 11 Dec 2024 21:51:43 +0100 Subject: [PATCH] perf: Reduce size of initial request message when no custom factory is provided --- .../detail/register_callback_rpc_handler.hpp | 15 +- .../detail/register_coroutine_rpc_handler.hpp | 7 +- .../detail/register_sender_rpc_handler.hpp | 14 +- .../detail/register_yield_rpc_handler.hpp | 7 +- .../detail/server_rpc_request_message.hpp | 48 ++++ src/agrpc/detail/server_rpc_starter.hpp | 248 +++++++++--------- src/agrpc/detail/server_rpc_with_request.hpp | 15 +- src/agrpc/register_awaitable_rpc_handler.hpp | 5 +- src/agrpc/register_callback_rpc_handler.hpp | 4 +- src/agrpc/register_sender_rpc_handler.hpp | 7 +- 10 files changed, 222 insertions(+), 148 deletions(-) create mode 100644 src/agrpc/detail/server_rpc_request_message.hpp diff --git a/src/agrpc/detail/register_callback_rpc_handler.hpp b/src/agrpc/detail/register_callback_rpc_handler.hpp index 8e2c577e..398db7e7 100644 --- a/src/agrpc/detail/register_callback_rpc_handler.hpp +++ b/src/agrpc/detail/register_callback_rpc_handler.hpp @@ -37,12 +37,13 @@ struct RegisterCallbackRPCHandlerOperation using typename Base::Service; using ServerRPCWithRequest = detail::ServerRPCWithRequest; using ServerRPCPtr = agrpc::ServerRPCPtr; + using Starter = detail::ServerRPCStarter<>; - struct ServerRPCAllocation - : detail::RequestMessageFactoryServerRPCMixinT + struct ServerRPCAllocation : detail::ServerRPCPtrRequestMessageFactoryT { ServerRPCAllocation(const ServerRPCExecutor& executor, RegisterCallbackRPCHandlerOperation& self) - : ServerRPCAllocation::RequestMessageFactoryMixin(self.rpc_handler(), executor), self_(self) + : detail::ServerRPCPtrRequestMessageFactoryT(self.rpc_handler(), executor), + self_(self) { } @@ -61,8 +62,8 @@ struct RegisterCallbackRPCHandlerOperation AGRPC_TRY { self_.initiate_next(); - auto& starter = *static_cast(ptr_.server_rpc_); - starter.invoke(self_.rpc_handler(), static_cast(ptr_)); + auto& rpc = *static_cast(ptr_.server_rpc_); + Starter::invoke(self_.rpc_handler(), static_cast(ptr_), rpc); } AGRPC_CATCH(...) { @@ -152,8 +153,8 @@ struct RegisterCallbackRPCHandlerOperation void perform_request_and_repeat(ServerRPCPtr&& ptr) { - auto& rpc = *ptr.server_rpc_; - rpc.start(rpc.rpc_, this->service(), StartCallback{*this, static_cast(ptr)}); + auto& rpc = *static_cast(ptr.server_rpc_); + Starter::start(rpc.rpc_, this->service(), rpc, StartCallback{*this, static_cast(ptr)}); } }; diff --git a/src/agrpc/detail/register_coroutine_rpc_handler.hpp b/src/agrpc/detail/register_coroutine_rpc_handler.hpp index 23bff22a..12ff8d92 100644 --- a/src/agrpc/detail/register_coroutine_rpc_handler.hpp +++ b/src/agrpc/detail/register_coroutine_rpc_handler.hpp @@ -71,10 +71,11 @@ struct RegisterCoroutineRPCHandlerOperation template static Awaitable perform_request_and_repeat(RefCountGuard g, Args... args) { + using Starter = detail::ServerRPCStarter; auto& self = static_cast(g.get().self_); auto rpc = detail::ServerRPCContextBaseAccess::construct(self.get_executor()); - detail::RequestMessageFactoryServerRPCStarter starter{self.rpc_handler()}; - if (!co_await starter.start(rpc, self.service(), self.completion_token())) + detail::ServerRPCRequestMessageFactoryT factory{self.rpc_handler()}; + if (!co_await Starter::start(rpc, self.service(), factory, self.completion_token())) { co_return; } @@ -82,7 +83,7 @@ struct RegisterCoroutineRPCHandlerOperation AGRPC_TRY { self.initiate_next(); - co_await starter.invoke(self.rpc_handler(), static_cast(args)..., rpc); + co_await Starter::invoke(self.rpc_handler(), static_cast(args)..., rpc, factory); } AGRPC_CATCH(...) { self.set_error(std::current_exception()); } if (!detail::ServerRPCContextBaseAccess::is_finished(rpc)) diff --git a/src/agrpc/detail/register_sender_rpc_handler.hpp b/src/agrpc/detail/register_sender_rpc_handler.hpp index 70fa631d..48ea28eb 100644 --- a/src/agrpc/detail/register_sender_rpc_handler.hpp +++ b/src/agrpc/detail/register_sender_rpc_handler.hpp @@ -157,8 +157,8 @@ struct RPCHandlerOperation { using Service = detail::ServerRPCServiceT; using Traits = typename ServerRPC::Traits; - using Starter = detail::RequestMessageFactoryServerRPCStarter; - using RPCHandlerInvokeResult = detail::RPCHandlerInvokeResultT; + using RequestMessageFactory = detail::ServerRPCRequestMessageFactoryT; + using RPCHandlerInvokeResult = detail::RPCHandlerInvokeResultT; using RegisterRPCHandlerSenderOperationBase = detail::RegisterRPCHandlerSenderOperationBase; @@ -206,10 +206,10 @@ struct RPCHandlerOperation #endif }; - using StartOperationState = detail::InplaceWithFunctionWrapper< - exec::connect_result_t().start(std::declval(), - std::declval(), agrpc::use_sender)), - StartReceiver>>; + using StartOperationState = detail::InplaceWithFunctionWrapper::start(std::declval(), std::declval(), + std::declval(), agrpc::use_sender)), + StartReceiver>>; template struct Receiver @@ -337,7 +337,7 @@ struct RPCHandlerOperation auto& get_allocator() noexcept { return impl2_.second(); } - detail::CompressedPair impl1_; + detail::CompressedPair impl1_; ServerRPC rpc_; detail::CompressedPair impl2_; }; diff --git a/src/agrpc/detail/register_yield_rpc_handler.hpp b/src/agrpc/detail/register_yield_rpc_handler.hpp index 272a2cf3..aedbfaea 100644 --- a/src/agrpc/detail/register_yield_rpc_handler.hpp +++ b/src/agrpc/detail/register_yield_rpc_handler.hpp @@ -53,6 +53,7 @@ struct RegisterYieldRPCHandlerOperation using typename Base::RefCountGuard; using typename Base::ServerRPCExecutor; using typename Base::Service; + using Starter = detail::ServerRPCStarter<>; template RegisterYieldRPCHandlerOperation(const ServerRPCExecutor& executor, Service& service, RPCHandler&& rpc_handler, @@ -86,8 +87,8 @@ struct RegisterYieldRPCHandlerOperation void perform_request_and_repeat(const Yield& yield) { auto rpc = detail::ServerRPCContextBaseAccess::construct(this->get_executor()); - detail::RequestMessageFactoryServerRPCStarter starter{this->rpc_handler()}; - if (!starter.start(rpc, this->service(), use_yield(yield))) + detail::ServerRPCRequestMessageFactoryT factory{this->rpc_handler()}; + if (!Starter::start(rpc, this->service(), factory, use_yield(yield))) { return; } @@ -95,7 +96,7 @@ struct RegisterYieldRPCHandlerOperation AGRPC_TRY { initiate_next(); - starter.invoke(this->rpc_handler(), rpc, yield); + Starter::invoke(this->rpc_handler(), rpc, factory, yield); } AGRPC_CATCH(...) { this->set_error(std::current_exception()); } if (!detail::ServerRPCContextBaseAccess::is_finished(rpc)) diff --git a/src/agrpc/detail/server_rpc_request_message.hpp b/src/agrpc/detail/server_rpc_request_message.hpp new file mode 100644 index 00000000..3fbd5100 --- /dev/null +++ b/src/agrpc/detail/server_rpc_request_message.hpp @@ -0,0 +1,48 @@ +// Copyright 2024 Dennis Hezel +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef AGRPC_DETAIL_SERVER_RPC_REQUEST_MESSAGE_HPP +#define AGRPC_DETAIL_SERVER_RPC_REQUEST_MESSAGE_HPP + +#include + +#include + +AGRPC_NAMESPACE_BEGIN() + +namespace detail +{ +template +struct ServerRPCRequestMessage +{ + static constexpr bool HAS_REQUEST_PTR = true; + + Request* request_; +}; + +template +struct ServerRPCRequestMessage +{ + static constexpr bool HAS_REQUEST_PTR = false; +}; + +constexpr bool has_initial_request(agrpc::ServerRPCType type) noexcept +{ + return type == agrpc::ServerRPCType::SERVER_STREAMING || type == agrpc::ServerRPCType::UNARY; +} +} + +AGRPC_NAMESPACE_END + +#endif // AGRPC_DETAIL_SERVER_RPC_REQUEST_MESSAGE_HPP diff --git a/src/agrpc/detail/server_rpc_starter.hpp b/src/agrpc/detail/server_rpc_starter.hpp index 1a81f4db..aefe5fb5 100644 --- a/src/agrpc/detail/server_rpc_starter.hpp +++ b/src/agrpc/detail/server_rpc_starter.hpp @@ -15,6 +15,7 @@ #ifndef AGRPC_DETAIL_SERVER_RPC_STARTER_HPP #define AGRPC_DETAIL_SERVER_RPC_STARTER_HPP +#include #include #include @@ -24,175 +25,182 @@ AGRPC_NAMESPACE_BEGIN() namespace detail { -constexpr bool has_initial_request(agrpc::ServerRPCType type) noexcept -{ - return type == agrpc::ServerRPCType::SERVER_STREAMING || type == agrpc::ServerRPCType::UNARY; -} +template +inline constexpr bool REQUEST_MESSAGE_FACTORY_HAS_DESTROY = false; -template -struct ServerRPCStarter -{ - template - auto start(agrpc::ServerRPC& rpc, Service& service, CompletionToken&& token) - { - using Responder = std::remove_reference_t; - return detail::async_initiate_sender_implementation( - RPCExecutorBaseAccess::grpc_context(rpc), - detail::ServerRequestSenderInitiation{service, *request_}, - detail::ServerRequestSenderImplementation{rpc}, - static_cast(token)); - } +template +inline constexpr bool REQUEST_MESSAGE_FACTORY_HAS_DESTROY().destroy( + std::declval()))> = true; - template - decltype(auto) invoke(RPCHandler&& handler, PrependedArgs&&... prepend, RPC&& rpc, AppendedArgs&&... append) - { - return static_cast(handler)(static_cast(prepend)..., static_cast(rpc), - *request_, static_cast(append)...); - } +using DefaultRequestMessageFactory = void; - Request* request_; +template +struct GetRPCHandlerRequestMessageFactory +{ + using Type = DefaultRequestMessageFactory; }; -template -struct ServerRPCStarter +template +struct GetRPCHandlerRequestMessageFactory().request_message_factory())> { - template - auto start(agrpc::ServerRPC& rpc, Service& service, CompletionToken&& token) - { - using Responder = std::remove_reference_t; - return detail::async_initiate_sender_implementation( - RPCExecutorBaseAccess::grpc_context(rpc), detail::ServerRequestSenderInitiation{service}, - detail::ServerRequestSenderImplementation{rpc}, - static_cast(token)); - } - - template - decltype(auto) invoke(RPCHandler&& handler, PrependedArgs&&... prepend, RPC&& rpc, AppendedArgs&&... append) - { - return static_cast(handler)(static_cast(prepend)..., static_cast(rpc), - static_cast(append)...); - } + using Type = decltype(std::declval().request_message_factory()); }; -template -using ServerRPCStarterT = detail::ServerRPCStarter; +template +using RPCHandlerRequestMessageFactoryT = typename GetRPCHandlerRequestMessageFactory::Type; -template -struct DefaultRequestMessageFactory +template