From 4b16f384cb6f0d703d3cd1f6745d58451d66573a Mon Sep 17 00:00:00 2001 From: Nikita Siniachenko Date: Tue, 18 Aug 2026 17:58:47 +0300 Subject: [PATCH 01/17] optimization: reserve header in request buffer to avoid copying and allocating --- runtime-light/stdlib/rpc/rpc-api.cpp | 56 +++++++++++++++++----------- runtime-light/tl/tl-core.h | 4 ++ 2 files changed, 39 insertions(+), 21 deletions(-) diff --git a/runtime-light/stdlib/rpc/rpc-api.cpp b/runtime-light/stdlib/rpc/rpc-api.cpp index c02e63ed5c..19aba53155 100644 --- a/runtime-light/stdlib/rpc/rpc-api.cpp +++ b/runtime-light/stdlib/rpc/rpc-api.cpp @@ -41,6 +41,8 @@ namespace kphp::rpc { namespace detail { +static constexpr size_t RESERVED_HEADER_SIZE{sizeof(kphp::rpc::dest_actor_flags_header)}; + mixed mixed_array_get_value(const mixed& arr, const string& str_key, int64_t num_key) noexcept { if (!arr.is_array()) [[unlikely]] { return {}; @@ -108,6 +110,15 @@ class_instance store_function(const mixed& tl_object) noexcept { return rpc_tl_query; } +// store bytes for `kphp::rpc::dest_actor_flags_header` in RpcServerInstanceState::tl_storer. +// we do this to avoid allocating new buffer for regularized rpc extra headers and copying whole request. +void reserve_header() noexcept { + auto& rpc_server_instance_st{RpcServerInstanceState::get()}; + kphp::rpc::dest_actor_flags_header reserved_header{}; + static_assert(sizeof(reserved_header) == RESERVED_HEADER_SIZE); + rpc_server_instance_st.tl_storer.store_bytes({reinterpret_cast(std::addressof(reserved_header)), sizeof(reserved_header)}); +} + kphp::rpc::query_info rpc_tl_query_one_impl(std::string_view actor, const mixed& tl_object, std::optional opt_timeout, bool collect_resp_extra_info, bool ignore_answer) noexcept { if (!tl_object.is_array()) [[unlikely]] { @@ -116,6 +127,7 @@ kphp::rpc::query_info rpc_tl_query_one_impl(std::string_view actor, const mixed& } f$rpc_clean(); + reserve_header(); auto rpc_tl_query{store_function(tl_object)}; // THROWING // handle exceptions that could arise during store_function if (!TlRpcError::transform_exception_into_error_if_possible().empty() || rpc_tl_query.is_null()) [[unlikely]] { @@ -137,6 +149,7 @@ kphp::rpc::query_info typed_rpc_tl_query_one_impl(std::string_view actor, const } f$rpc_clean(); + reserve_header(); auto fetcher{rpc_request.store_request()}; // THROWING // handle exceptions that could arise during store_request if (!TlRpcError::transform_exception_into_error_if_possible().empty() || !static_cast(fetcher)) [[unlikely]] { @@ -276,31 +289,32 @@ kphp::rpc::query_info send_request(std::string_view actor, std::optional const auto timestamp{std::chrono::duration{std::chrono::system_clock::now().time_since_epoch()}.count()}; - // if we have to allocate memory for request buffer, it will be in this vector, and it will be freed at the end of the function - std::optional> opt_request_vec{}; - std::span request_buffer{rpc_server_instance_st.tl_storer.view()}; + // We have reserved place for one `kphp::rpc::dest_actor_flags_header` in `rpc_server_instance_st.tl_storer` + // before storing request and calling `send_request(...)`, + // so the real serialized request starts after `RESERVED_HEADER_SIZE` bytes in tl storer. + // We do this to have enough place for regularized header after `kphp::rpc::regularize_extra_headers(...)` call. + // This optimization helps us avoid allocating and copying the whole request. + std::span request_buffer{rpc_server_instance_st.tl_storer.view().subspan(detail::RESERVED_HEADER_SIZE)}; if (const auto& [opt_new_extra_header, cur_extra_header_size]{kphp::rpc::regularize_extra_headers(request_buffer, ignore_answer)}; opt_new_extra_header) { std::span new_header{reinterpret_cast(std::addressof(*opt_new_extra_header)), sizeof(std::remove_cvref_t)}; - std::span request_body{rpc_server_instance_st.tl_storer.view().subspan(cur_extra_header_size)}; - - std::span new_request_buffer{}; - size_t request_and_headers_size{new_header.size() + request_body.size()}; - if (request_and_headers_size <= StringLibContext::STATIC_BUFFER_LENGTH) { - // we have enough space in static buffer to store request with regularized headers - auto& string_lib_ctx{StringLibContext::get()}; - new_request_buffer = std::span{reinterpret_cast(string_lib_ctx.static_buf.get()), request_and_headers_size}; - } else { - // we have to allocate buffer for request with regularized headers - opt_request_vec.emplace(request_and_headers_size); - new_request_buffer = std::span{opt_request_vec->data(), request_and_headers_size}; - } - - std::ranges::copy(new_header, new_request_buffer.subspan(0, new_header.size()).begin()); - std::ranges::copy(request_body, new_request_buffer.subspan(new_header.size()).begin()); - - request_buffer = new_request_buffer; + std::span request_body{request_buffer.subspan(cur_extra_header_size)}; + + // If `regularize_extra_headers` gave us new header, then we must serialize `new_header` before `request_body`. + // + // here serialized request (business logic) starts + // \/ + // tl_storer was: |reserved dest-actor-flags-header| [optional old header] |request-body| + // + // We want to serialize |our new header| right before |request-body| : + // + // tl_storer will be: ... may be some bytes leaved here ... |our new header| |request-body| + + // we do always have enough bytes for `new_header` before `request_body`, because we have reserved it before `send_request(...)` call. + size_t new_header_offset{detail::RESERVED_HEADER_SIZE + cur_extra_header_size - new_header.size()}; + request_buffer = rpc_server_instance_st.tl_storer.view().subspan(new_header_offset); + std::ranges::copy(new_header, request_buffer.data()); } const size_t request_size{request_buffer.size_bytes()}; diff --git a/runtime-light/tl/tl-core.h b/runtime-light/tl/tl-core.h index 51f1ec99a0..8226b40ecb 100644 --- a/runtime-light/tl/tl-core.h +++ b/runtime-light/tl/tl-core.h @@ -54,6 +54,10 @@ class storer { return m_buffer; } + std::span view() noexcept { + return m_buffer; + } + void clear() noexcept { m_buffer.clear(); } From e9438db4cc327ca45833278c07819ff4efcbc3e4 Mon Sep 17 00:00:00 2001 From: Nikita Siniachenko Date: Wed, 19 Aug 2026 10:39:38 +0300 Subject: [PATCH 02/17] debug logginb for RpcError and RpcResult fetchers and for all co_return's from rpc_tl_query_result_one_impl --- runtime-light/stdlib/rpc/rpc-api.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/runtime-light/stdlib/rpc/rpc-api.cpp b/runtime-light/stdlib/rpc/rpc-api.cpp index 19aba53155..1bd95f50b4 100644 --- a/runtime-light/stdlib/rpc/rpc-api.cpp +++ b/runtime-light/stdlib/rpc/rpc-api.cpp @@ -82,9 +82,11 @@ class_instance fetch_function_typed(const class_instance, err.try_fetch())) { + kphp::log::warning("!!! fetch_function_typed -> error"); return error_factory.make_error(std::move(err)); } + kphp::log::warning("!!! fetch_function_typed -> response"); // TODO: EOF handling return TRY_CALL(class_instance, class_instance, rpc_query.get()->result_fetcher->fetch_typed_response()); } @@ -226,6 +228,7 @@ kphp::coro::task> rpc_tl_query_result_one_impl(int64_t query_id) no kphp::coro::task> typed_rpc_tl_query_result_one_impl(int64_t query_id, const RpcErrorFactory& error_factory) noexcept { if (query_id < kphp::rpc::VALID_QUERY_ID_RANGE_START) [[unlikely]] { + kphp::log::warning("--- A ---"); co_return error_factory.make_error(TL_ERROR_WRONG_QUERY_ID, string{"wrong query_id"}); } @@ -247,6 +250,7 @@ kphp::coro::task> typed_rpc_tl_query_result_ if (it_response_fetcher == rpc_client_instance_st.response_fetcher_instances.end() || it_fork_task == rpc_client_instance_st.response_awaiter_tasks.end()) [[unlikely]] { + kphp::log::warning("--- B ---"); co_return error_factory.make_error(TL_ERROR_INTERNAL, string{"unexpectedly could not find query in pending queries"}); } rpc_query = std::move(it_response_fetcher->second); @@ -254,18 +258,22 @@ kphp::coro::task> typed_rpc_tl_query_result_ } if (rpc_query.is_null()) [[unlikely]] { + kphp::log::warning("--- C ---"); co_return error_factory.make_error(TL_ERROR_INTERNAL, string{"can't use rpc_tl_query_result for non-TL query"}); } if (!rpc_query.get()->result_fetcher || rpc_query.get()->result_fetcher->empty()) [[unlikely]] { + kphp::log::warning("--- D ---"); co_return error_factory.make_error(TL_ERROR_INTERNAL, string{"rpc query has empty result fetcher"}); } if (!rpc_query.get()->result_fetcher->is_typed) [[unlikely]] { + kphp::log::warning("--- E ---"); co_return error_factory.make_error(TL_ERROR_INTERNAL, string{"can't get typed result from untyped TL query. Use consistent API for that"}); } kphp::log::assertion(opt_awaiter_task.has_value()); auto response_expected{co_await kphp::forks::id_managed(*std::exchange(opt_awaiter_task, std::nullopt))}; if (!response_expected) [[unlikely]] { + kphp::log::warning("--- F ---"); co_return error_factory.make_error(response_expected.error(), string{"can't fetch rpc response"}); } @@ -276,8 +284,10 @@ kphp::coro::task> typed_rpc_tl_query_result_ auto res{fetch_function_typed(rpc_query, error_factory)}; // THROWING // handle exceptions that could arise during fetch_function_typed if (auto err{error_factory.transform_exception_into_error_if_possible()}; !err.is_null()) [[unlikely]] { + kphp::log::warning("--- G ---"); co_return std::move(err); } + kphp::log::warning("+++ H +++"); co_return std::move(res); } From e7921621c9871c9b6f4a3c3a2c20891a2014bb6c Mon Sep 17 00:00:00 2001 From: Nikita Siniachenko Date: Wed, 19 Aug 2026 10:51:37 +0300 Subject: [PATCH 03/17] debug log rpc err code and msg --- runtime-light/stdlib/rpc/rpc-api.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime-light/stdlib/rpc/rpc-api.cpp b/runtime-light/stdlib/rpc/rpc-api.cpp index 1bd95f50b4..551db1a433 100644 --- a/runtime-light/stdlib/rpc/rpc-api.cpp +++ b/runtime-light/stdlib/rpc/rpc-api.cpp @@ -82,7 +82,7 @@ class_instance fetch_function_typed(const class_instance, err.try_fetch())) { - kphp::log::warning("!!! fetch_function_typed -> error"); + kphp::log::warning("!!! fetch_function_typed -> error {}: {}", err.error_code, err.error_msg.c_str()); return error_factory.make_error(std::move(err)); } From 428a407e957dfdd9cd95061d7c1ebce63b07da82 Mon Sep 17 00:00:00 2001 From: Nikita Siniachenko Date: Wed, 19 Aug 2026 11:39:09 +0300 Subject: [PATCH 04/17] OPTIMIZATION SUCKS debug logs --- runtime-light/stdlib/rpc/rpc-api.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/runtime-light/stdlib/rpc/rpc-api.cpp b/runtime-light/stdlib/rpc/rpc-api.cpp index 551db1a433..5538d1f638 100644 --- a/runtime-light/stdlib/rpc/rpc-api.cpp +++ b/runtime-light/stdlib/rpc/rpc-api.cpp @@ -323,6 +323,16 @@ kphp::rpc::query_info send_request(std::string_view actor, std::optional // we do always have enough bytes for `new_header` before `request_body`, because we have reserved it before `send_request(...)` call. size_t new_header_offset{detail::RESERVED_HEADER_SIZE + cur_extra_header_size - new_header.size()}; + + kphp::log::warning("OPTIMIZATION SUCKS: {} - {} - {} - {} - {} - {} - {}", + reinterpret_cast(rpc_server_instance_st.tl_storer.view().data()), + reinterpret_cast(request_buffer.data()), + reinterpret_cast(request_body.data()), + detail::RESERVED_HEADER_SIZE, + cur_extra_header_size, + new_header.size(), + reinterpret_cast(rpc_server_instance_st.tl_storer.view().subspan(new_header_offset).data())); + request_buffer = rpc_server_instance_st.tl_storer.view().subspan(new_header_offset); std::ranges::copy(new_header, request_buffer.data()); } From 6c632d3912f0a220af502b0809f32591ee502d1b Mon Sep 17 00:00:00 2001 From: Nikita Siniachenko Date: Wed, 19 Aug 2026 13:09:32 +0300 Subject: [PATCH 05/17] try to debug fetch our request with header --- runtime-light/stdlib/rpc/rpc-api.cpp | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/runtime-light/stdlib/rpc/rpc-api.cpp b/runtime-light/stdlib/rpc/rpc-api.cpp index 5538d1f638..d5f04f0fa2 100644 --- a/runtime-light/stdlib/rpc/rpc-api.cpp +++ b/runtime-light/stdlib/rpc/rpc-api.cpp @@ -335,6 +335,28 @@ kphp::rpc::query_info send_request(std::string_view actor, std::optional request_buffer = rpc_server_instance_st.tl_storer.view().subspan(new_header_offset); std::ranges::copy(new_header, request_buffer.data()); + + tl::magic magic; + tl::i64 actor_id{}; + tl::mask flags{}; + tl::rpcInvokeReqExtra extra{}; + tl::magic op; + + tl::fetcher debug_fetcher{request_buffer}; + + kphp::log::assertion(magic.fetch(debug_fetcher)); + kphp::log::assertion(magic.expect(TL_RPC_DEST_ACTOR_FLAGS)); + + kphp::log::assertion(actor_id.fetch(debug_fetcher)); + kphp::log::assertion(actor_id.value == 0); + + kphp::log::assertion(flags.fetch(debug_fetcher)); + + kphp::log::assertion(extra.fetch(debug_fetcher, flags)); + + kphp::log::assertion(op.fetch(debug_fetcher)); + + kphp::log::warning("REQUEST OP IS {:x}", op.value); } const size_t request_size{request_buffer.size_bytes()}; From e96168f7a24aa150094bedf3a9a1c5dc7ffcd199 Mon Sep 17 00:00:00 2001 From: Nikita Siniachenko Date: Wed, 19 Aug 2026 17:26:10 +0300 Subject: [PATCH 06/17] AGAIN LOGS MUZZER FUCKER --- runtime-light/stdlib/rpc/rpc-api.cpp | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/runtime-light/stdlib/rpc/rpc-api.cpp b/runtime-light/stdlib/rpc/rpc-api.cpp index d5f04f0fa2..1be6d79df8 100644 --- a/runtime-light/stdlib/rpc/rpc-api.cpp +++ b/runtime-light/stdlib/rpc/rpc-api.cpp @@ -357,6 +357,27 @@ kphp::rpc::query_info send_request(std::string_view actor, std::optional kphp::log::assertion(op.fetch(debug_fetcher)); kphp::log::warning("REQUEST OP IS {:x}", op.value); + + } else { + + tl::fetcher debug_fetcher{request_buffer}; + + tl::magic magic; + + kphp::log::assertion(magic.fetch(debug_fetcher)); + + if (magic.expect(TL_RPC_DEST_ACTOR)) { + tl::i64 actor_id{}; + kphp::log::assertion(actor_id.fetch(debug_fetcher)); + + kphp::log::assertion(magic.fetch(debug_fetcher)); + } + + kphp::log::assertion(!magic.expect(TL_RPC_DEST_ACTOR_FLAGS)); + kphp::log::assertion(!magic.expect(TL_RPC_DEST_FLAGS)); + kphp::log::assertion(!magic.expect(TL_RPC_DEST_ACTOR)); + + kphp::log::warning("request OP IS {:x}", magic.value); } const size_t request_size{request_buffer.size_bytes()}; From d135e1aa5922e149d73ab148b4795ea2066ad70c Mon Sep 17 00:00:00 2001 From: Nikita Siniachenko Date: Wed, 19 Aug 2026 18:05:42 +0300 Subject: [PATCH 07/17] debug request op after reserved header --- runtime-light/stdlib/rpc/rpc-api.cpp | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/runtime-light/stdlib/rpc/rpc-api.cpp b/runtime-light/stdlib/rpc/rpc-api.cpp index 1be6d79df8..474795928c 100644 --- a/runtime-light/stdlib/rpc/rpc-api.cpp +++ b/runtime-light/stdlib/rpc/rpc-api.cpp @@ -305,6 +305,15 @@ kphp::rpc::query_info send_request(std::string_view actor, std::optional // We do this to have enough place for regularized header after `kphp::rpc::regularize_extra_headers(...)` call. // This optimization helps us avoid allocating and copying the whole request. std::span request_buffer{rpc_server_instance_st.tl_storer.view().subspan(detail::RESERVED_HEADER_SIZE)}; + tl::magic magic; + tl::fetcher debug_fetcherrr{request_buffer}; + kphp::log::assertion(magic.fetch(debug_fetcherrr)); + kphp::log::warning("request_buffer start op: {:x}", magic.value); + if (magic.value == TL_RPC_DEST_ACTOR) { + debug_fetcherrr = tl::fetcher{request_buffer.subspan(sizeof(kphp::rpc::dest_actor_header))}; + kphp::log::assertion(magic.fetch(debug_fetcherrr)); + kphp::log::warning("request_buffer start op AFTER DEST ACTOR: {:x}", magic.value); + } if (const auto& [opt_new_extra_header, cur_extra_header_size]{kphp::rpc::regularize_extra_headers(request_buffer, ignore_answer)}; opt_new_extra_header) { std::span new_header{reinterpret_cast(std::addressof(*opt_new_extra_header)), @@ -366,7 +375,9 @@ kphp::rpc::query_info send_request(std::string_view actor, std::optional kphp::log::assertion(magic.fetch(debug_fetcher)); + bool was_dest_actor_header = false; if (magic.expect(TL_RPC_DEST_ACTOR)) { + was_dest_actor_header = true; tl::i64 actor_id{}; kphp::log::assertion(actor_id.fetch(debug_fetcher)); @@ -377,7 +388,7 @@ kphp::rpc::query_info send_request(std::string_view actor, std::optional kphp::log::assertion(!magic.expect(TL_RPC_DEST_FLAGS)); kphp::log::assertion(!magic.expect(TL_RPC_DEST_ACTOR)); - kphp::log::warning("request OP IS {:x}", magic.value); + kphp::log::warning("request OP IS {:x} was_dest_actor_header({})", magic.value, was_dest_actor_header); } const size_t request_size{request_buffer.size_bytes()}; From ba326e2145b6e2b550690afb9e9a7f627720b122 Mon Sep 17 00:00:00 2001 From: Nikita Siniachenko Date: Wed, 19 Aug 2026 18:39:29 +0300 Subject: [PATCH 08/17] check reserved header buffer is zeroed --- runtime-light/stdlib/rpc/rpc-api.cpp | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/runtime-light/stdlib/rpc/rpc-api.cpp b/runtime-light/stdlib/rpc/rpc-api.cpp index 474795928c..2a86b32fa7 100644 --- a/runtime-light/stdlib/rpc/rpc-api.cpp +++ b/runtime-light/stdlib/rpc/rpc-api.cpp @@ -152,11 +152,23 @@ kphp::rpc::query_info typed_rpc_tl_query_one_impl(std::string_view actor, const f$rpc_clean(); reserve_header(); + auto& rpc_server_instance_st{RpcServerInstanceState::get()}; + auto sp{rpc_server_instance_st.tl_storer.view().subspan(0, detail::RESERVED_HEADER_SIZE)}; + for (auto b : sp) { + if (b != static_cast(0)) { + kphp::log::error("A SERVER RESERVED HEADER BUFFER IS NOT ZEROED"); + } + } auto fetcher{rpc_request.store_request()}; // THROWING // handle exceptions that could arise during store_request if (!TlRpcError::transform_exception_into_error_if_possible().empty() || !static_cast(fetcher)) [[unlikely]] { return kphp::rpc::query_info{}; } + for (auto b : sp) { + if (b != static_cast(0)) { + kphp::log::error("B SERVER RESERVED HEADER BUFFER IS NOT ZEROED"); + } + } const auto query_info{kphp::rpc::send_request(actor, opt_timeout, ignore_answer, collect_responses_extra_info)}; if (!ignore_answer) { @@ -305,6 +317,12 @@ kphp::rpc::query_info send_request(std::string_view actor, std::optional // We do this to have enough place for regularized header after `kphp::rpc::regularize_extra_headers(...)` call. // This optimization helps us avoid allocating and copying the whole request. std::span request_buffer{rpc_server_instance_st.tl_storer.view().subspan(detail::RESERVED_HEADER_SIZE)}; + auto sp{rpc_server_instance_st.tl_storer.view().subspan(0, detail::RESERVED_HEADER_SIZE)}; + for (auto b : sp) { + if (b != static_cast(0)) { + kphp::log::error("C SERVER RESERVED HEADER BUFFER IS NOT ZEROED"); + } + } tl::magic magic; tl::fetcher debug_fetcherrr{request_buffer}; kphp::log::assertion(magic.fetch(debug_fetcherrr)); From 0904ed70d9c9b7762026520082bc2765a96502a9 Mon Sep 17 00:00:00 2001 From: Nikita Siniachenko Date: Thu, 20 Aug 2026 12:01:06 +0300 Subject: [PATCH 09/17] fixed UB in assert --- runtime-light/stdlib/rpc/rpc-api.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/runtime-light/stdlib/rpc/rpc-api.cpp b/runtime-light/stdlib/rpc/rpc-api.cpp index 2a86b32fa7..36832cfa39 100644 --- a/runtime-light/stdlib/rpc/rpc-api.cpp +++ b/runtime-light/stdlib/rpc/rpc-api.cpp @@ -164,6 +164,7 @@ kphp::rpc::query_info typed_rpc_tl_query_one_impl(std::string_view actor, const if (!TlRpcError::transform_exception_into_error_if_possible().empty() || !static_cast(fetcher)) [[unlikely]] { return kphp::rpc::query_info{}; } + sp = rpc_server_instance_st.tl_storer.view().subspan(0, detail::RESERVED_HEADER_SIZE); for (auto b : sp) { if (b != static_cast(0)) { kphp::log::error("B SERVER RESERVED HEADER BUFFER IS NOT ZEROED"); From 15e3df1727c1c0531f8915db42f6d554583a3b3f Mon Sep 17 00:00:00 2001 From: Nikita Siniachenko Date: Thu, 20 Aug 2026 12:14:09 +0300 Subject: [PATCH 10/17] extra check --- runtime-light/stdlib/rpc/rpc-api.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/runtime-light/stdlib/rpc/rpc-api.cpp b/runtime-light/stdlib/rpc/rpc-api.cpp index 36832cfa39..84e5ffa6ba 100644 --- a/runtime-light/stdlib/rpc/rpc-api.cpp +++ b/runtime-light/stdlib/rpc/rpc-api.cpp @@ -156,7 +156,7 @@ kphp::rpc::query_info typed_rpc_tl_query_one_impl(std::string_view actor, const auto sp{rpc_server_instance_st.tl_storer.view().subspan(0, detail::RESERVED_HEADER_SIZE)}; for (auto b : sp) { if (b != static_cast(0)) { - kphp::log::error("A SERVER RESERVED HEADER BUFFER IS NOT ZEROED"); + kphp::log::error("AAA SERVER RESERVED HEADER BUFFER IS NOT ZEROED"); } } auto fetcher{rpc_request.store_request()}; // THROWING @@ -165,9 +165,10 @@ kphp::rpc::query_info typed_rpc_tl_query_one_impl(std::string_view actor, const return kphp::rpc::query_info{}; } sp = rpc_server_instance_st.tl_storer.view().subspan(0, detail::RESERVED_HEADER_SIZE); + kphp::log::warning("NEW TL STORER TAKEN {}", sp.data() == rpc_server_instance_st.tl_storer.view().data()); for (auto b : sp) { if (b != static_cast(0)) { - kphp::log::error("B SERVER RESERVED HEADER BUFFER IS NOT ZEROED"); + kphp::log::error("BBB SERVER RESERVED HEADER BUFFER IS NOT ZEROED"); } } From f3d0d6f490548f22f37edebaca53607da78b19db Mon Sep 17 00:00:00 2001 From: Nikita Siniachenko Date: Thu, 20 Aug 2026 12:22:19 +0300 Subject: [PATCH 11/17] output tl function name --- runtime-light/stdlib/rpc/rpc-api.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/runtime-light/stdlib/rpc/rpc-api.cpp b/runtime-light/stdlib/rpc/rpc-api.cpp index 84e5ffa6ba..423091fb4e 100644 --- a/runtime-light/stdlib/rpc/rpc-api.cpp +++ b/runtime-light/stdlib/rpc/rpc-api.cpp @@ -166,6 +166,7 @@ kphp::rpc::query_info typed_rpc_tl_query_one_impl(std::string_view actor, const } sp = rpc_server_instance_st.tl_storer.view().subspan(0, detail::RESERVED_HEADER_SIZE); kphp::log::warning("NEW TL STORER TAKEN {}", sp.data() == rpc_server_instance_st.tl_storer.view().data()); + kphp::log::warning("TL FUNCTION NAME: {}", rpc_request.tl_function_name().c_str()); for (auto b : sp) { if (b != static_cast(0)) { kphp::log::error("BBB SERVER RESERVED HEADER BUFFER IS NOT ZEROED"); From e021a96b71b46f5f3129ddbe98dcf9f7d4a62cc0 Mon Sep 17 00:00:00 2001 From: Nikita Siniachenko Date: Fri, 21 Aug 2026 15:03:02 +0300 Subject: [PATCH 12/17] reserve header in f() and dkip it in f() --- runtime-light/server/rpc/init-functions.cpp | 1 + runtime-light/stdlib/rpc/rpc-api.cpp | 47 +++++++-------------- runtime-light/stdlib/rpc/rpc-api.h | 20 +++++++-- 3 files changed, 33 insertions(+), 35 deletions(-) diff --git a/runtime-light/server/rpc/init-functions.cpp b/runtime-light/server/rpc/init-functions.cpp index 58ae0c767e..9416bebba6 100644 --- a/runtime-light/server/rpc/init-functions.cpp +++ b/runtime-light/server/rpc/init-functions.cpp @@ -194,6 +194,7 @@ void init_server(kphp::component::stream&& request_stream, kphp::stl::vector fetch_function_typed(const class_instance, err.try_fetch())) { - kphp::log::warning("!!! fetch_function_typed -> error {}: {}", err.error_code, err.error_msg.c_str()); + // kphp::log::warning("!!! fetch_function_typed -> error {}: {}", err.error_code, err.error_msg.c_str()); return error_factory.make_error(std::move(err)); } - kphp::log::warning("!!! fetch_function_typed -> response"); + // kphp::log::warning("!!! fetch_function_typed -> response"); // TODO: EOF handling return TRY_CALL(class_instance, class_instance, rpc_query.get()->result_fetcher->fetch_typed_response()); } @@ -112,15 +110,6 @@ class_instance store_function(const mixed& tl_object) noexcept { return rpc_tl_query; } -// store bytes for `kphp::rpc::dest_actor_flags_header` in RpcServerInstanceState::tl_storer. -// we do this to avoid allocating new buffer for regularized rpc extra headers and copying whole request. -void reserve_header() noexcept { - auto& rpc_server_instance_st{RpcServerInstanceState::get()}; - kphp::rpc::dest_actor_flags_header reserved_header{}; - static_assert(sizeof(reserved_header) == RESERVED_HEADER_SIZE); - rpc_server_instance_st.tl_storer.store_bytes({reinterpret_cast(std::addressof(reserved_header)), sizeof(reserved_header)}); -} - kphp::rpc::query_info rpc_tl_query_one_impl(std::string_view actor, const mixed& tl_object, std::optional opt_timeout, bool collect_resp_extra_info, bool ignore_answer) noexcept { if (!tl_object.is_array()) [[unlikely]] { @@ -129,7 +118,6 @@ kphp::rpc::query_info rpc_tl_query_one_impl(std::string_view actor, const mixed& } f$rpc_clean(); - reserve_header(); auto rpc_tl_query{store_function(tl_object)}; // THROWING // handle exceptions that could arise during store_function if (!TlRpcError::transform_exception_into_error_if_possible().empty() || rpc_tl_query.is_null()) [[unlikely]] { @@ -151,7 +139,6 @@ kphp::rpc::query_info typed_rpc_tl_query_one_impl(std::string_view actor, const } f$rpc_clean(); - reserve_header(); auto& rpc_server_instance_st{RpcServerInstanceState::get()}; auto sp{rpc_server_instance_st.tl_storer.view().subspan(0, detail::RESERVED_HEADER_SIZE)}; for (auto b : sp) { @@ -165,8 +152,6 @@ kphp::rpc::query_info typed_rpc_tl_query_one_impl(std::string_view actor, const return kphp::rpc::query_info{}; } sp = rpc_server_instance_st.tl_storer.view().subspan(0, detail::RESERVED_HEADER_SIZE); - kphp::log::warning("NEW TL STORER TAKEN {}", sp.data() == rpc_server_instance_st.tl_storer.view().data()); - kphp::log::warning("TL FUNCTION NAME: {}", rpc_request.tl_function_name().c_str()); for (auto b : sp) { if (b != static_cast(0)) { kphp::log::error("BBB SERVER RESERVED HEADER BUFFER IS NOT ZEROED"); @@ -302,7 +287,6 @@ kphp::coro::task> typed_rpc_tl_query_result_ kphp::log::warning("--- G ---"); co_return std::move(err); } - kphp::log::warning("+++ H +++"); co_return std::move(res); } @@ -329,11 +313,10 @@ kphp::rpc::query_info send_request(std::string_view actor, std::optional tl::magic magic; tl::fetcher debug_fetcherrr{request_buffer}; kphp::log::assertion(magic.fetch(debug_fetcherrr)); - kphp::log::warning("request_buffer start op: {:x}", magic.value); if (magic.value == TL_RPC_DEST_ACTOR) { debug_fetcherrr = tl::fetcher{request_buffer.subspan(sizeof(kphp::rpc::dest_actor_header))}; kphp::log::assertion(magic.fetch(debug_fetcherrr)); - kphp::log::warning("request_buffer start op AFTER DEST ACTOR: {:x}", magic.value); + // kphp::log::warning("request_buffer start op AFTER DEST ACTOR: {:x}", magic.value); } if (const auto& [opt_new_extra_header, cur_extra_header_size]{kphp::rpc::regularize_extra_headers(request_buffer, ignore_answer)}; opt_new_extra_header) { @@ -354,14 +337,14 @@ kphp::rpc::query_info send_request(std::string_view actor, std::optional // we do always have enough bytes for `new_header` before `request_body`, because we have reserved it before `send_request(...)` call. size_t new_header_offset{detail::RESERVED_HEADER_SIZE + cur_extra_header_size - new_header.size()}; - kphp::log::warning("OPTIMIZATION SUCKS: {} - {} - {} - {} - {} - {} - {}", - reinterpret_cast(rpc_server_instance_st.tl_storer.view().data()), - reinterpret_cast(request_buffer.data()), - reinterpret_cast(request_body.data()), - detail::RESERVED_HEADER_SIZE, - cur_extra_header_size, - new_header.size(), - reinterpret_cast(rpc_server_instance_st.tl_storer.view().subspan(new_header_offset).data())); + // kphp::log::warning("OPTIMIZATION SUCKS: {} - {} - {} - {} - {} - {} - {}", + // reinterpret_cast(rpc_server_instance_st.tl_storer.view().data()), + // reinterpret_cast(request_buffer.data()), + // reinterpret_cast(request_body.data()), + // detail::RESERVED_HEADER_SIZE, + // cur_extra_header_size, + // new_header.size(), + // reinterpret_cast(rpc_server_instance_st.tl_storer.view().subspan(new_header_offset).data())); request_buffer = rpc_server_instance_st.tl_storer.view().subspan(new_header_offset); std::ranges::copy(new_header, request_buffer.data()); @@ -386,7 +369,7 @@ kphp::rpc::query_info send_request(std::string_view actor, std::optional kphp::log::assertion(op.fetch(debug_fetcher)); - kphp::log::warning("REQUEST OP IS {:x}", op.value); + // kphp::log::warning("REQUEST OP IS {:x}", op.value); } else { @@ -396,9 +379,9 @@ kphp::rpc::query_info send_request(std::string_view actor, std::optional kphp::log::assertion(magic.fetch(debug_fetcher)); - bool was_dest_actor_header = false; + // bool was_dest_actor_header = false; if (magic.expect(TL_RPC_DEST_ACTOR)) { - was_dest_actor_header = true; + // was_dest_actor_header = true; tl::i64 actor_id{}; kphp::log::assertion(actor_id.fetch(debug_fetcher)); @@ -409,7 +392,7 @@ kphp::rpc::query_info send_request(std::string_view actor, std::optional kphp::log::assertion(!magic.expect(TL_RPC_DEST_FLAGS)); kphp::log::assertion(!magic.expect(TL_RPC_DEST_ACTOR)); - kphp::log::warning("request OP IS {:x} was_dest_actor_header({})", magic.value, was_dest_actor_header); + // kphp::log::warning("request OP IS {:x} was_dest_actor_header({})", magic.value, was_dest_actor_header); } const size_t request_size{request_buffer.size_bytes()}; diff --git a/runtime-light/stdlib/rpc/rpc-api.h b/runtime-light/stdlib/rpc/rpc-api.h index d02358bd44..5f12175beb 100644 --- a/runtime-light/stdlib/rpc/rpc-api.h +++ b/runtime-light/stdlib/rpc/rpc-api.h @@ -24,6 +24,7 @@ #include "runtime-light/stdlib/rpc/rpc-client-state.h" #include "runtime-light/stdlib/rpc/rpc-constants.h" #include "runtime-light/stdlib/rpc/rpc-exceptions.h" +#include "runtime-light/stdlib/rpc/rpc-extra-headers.h" #include "runtime-light/stdlib/rpc/rpc-extra-info.h" #include "runtime-light/stdlib/rpc/rpc-tl-error.h" #include "runtime-light/stdlib/rpc/rpc-tl-function.h" @@ -58,6 +59,17 @@ inline kphp::coro::task> send_response(std::span(std::addressof(reserved_header)), sizeof(reserved_header)}); +} + kphp::rpc::query_info rpc_tl_query_one_impl(std::string_view actor, const mixed& tl_object, std::optional opt_timeout, bool collect_resp_extra_info, bool ignore_answer) noexcept; @@ -199,7 +211,8 @@ inline void f$fetch_raw_vector_double(array& vector, int64_t num_elems) inline bool f$rpc_clean() noexcept { auto& rpc_server_instance_st{RpcServerInstanceState::get()}; rpc_server_instance_st.tl_storer.clear(); - rpc_server_instance_st.tl_fetcher = tl::fetcher{rpc_server_instance_st.tl_storer.view()}; + kphp::rpc::detail::reserve_header(); + rpc_server_instance_st.tl_fetcher = tl::fetcher{rpc_server_instance_st.tl_storer.view().subspan(kphp::rpc::detail::RESERVED_HEADER_SIZE)}; return true; } @@ -268,8 +281,9 @@ inline kphp::coro::task<> f$rpc_server_store_response(class_instance Date: Fri, 21 Aug 2026 18:05:07 +0300 Subject: [PATCH 13/17] rmm --- runtime-light/stdlib/rpc/rpc-api.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/runtime-light/stdlib/rpc/rpc-api.cpp b/runtime-light/stdlib/rpc/rpc-api.cpp index 416d4bcf0d..c39d1bd927 100644 --- a/runtime-light/stdlib/rpc/rpc-api.cpp +++ b/runtime-light/stdlib/rpc/rpc-api.cpp @@ -353,7 +353,7 @@ kphp::rpc::query_info send_request(std::string_view actor, std::optional tl::i64 actor_id{}; tl::mask flags{}; tl::rpcInvokeReqExtra extra{}; - tl::magic op; + // tl::magic op; tl::fetcher debug_fetcher{request_buffer}; @@ -365,9 +365,9 @@ kphp::rpc::query_info send_request(std::string_view actor, std::optional kphp::log::assertion(flags.fetch(debug_fetcher)); - kphp::log::assertion(extra.fetch(debug_fetcher, flags)); + // kphp::log::assertion(extra.fetch(debug_fetcher, flags)); - kphp::log::assertion(op.fetch(debug_fetcher)); + // kphp::log::assertion(op.fetch(debug_fetcher)); // kphp::log::warning("REQUEST OP IS {:x}", op.value); From 0e204e617cd5298029843fb25b46681e1c51f276 Mon Sep 17 00:00:00 2001 From: Nikita Siniachenko Date: Mon, 24 Aug 2026 12:02:19 +0300 Subject: [PATCH 14/17] finall ..... removed debug logs --- runtime-light/stdlib/rpc/rpc-api.cpp | 91 ---------------------------- 1 file changed, 91 deletions(-) diff --git a/runtime-light/stdlib/rpc/rpc-api.cpp b/runtime-light/stdlib/rpc/rpc-api.cpp index c39d1bd927..3ff445d7de 100644 --- a/runtime-light/stdlib/rpc/rpc-api.cpp +++ b/runtime-light/stdlib/rpc/rpc-api.cpp @@ -80,11 +80,9 @@ class_instance fetch_function_typed(const class_instance, err.try_fetch())) { - // kphp::log::warning("!!! fetch_function_typed -> error {}: {}", err.error_code, err.error_msg.c_str()); return error_factory.make_error(std::move(err)); } - // kphp::log::warning("!!! fetch_function_typed -> response"); // TODO: EOF handling return TRY_CALL(class_instance, class_instance, rpc_query.get()->result_fetcher->fetch_typed_response()); } @@ -139,24 +137,11 @@ kphp::rpc::query_info typed_rpc_tl_query_one_impl(std::string_view actor, const } f$rpc_clean(); - auto& rpc_server_instance_st{RpcServerInstanceState::get()}; - auto sp{rpc_server_instance_st.tl_storer.view().subspan(0, detail::RESERVED_HEADER_SIZE)}; - for (auto b : sp) { - if (b != static_cast(0)) { - kphp::log::error("AAA SERVER RESERVED HEADER BUFFER IS NOT ZEROED"); - } - } auto fetcher{rpc_request.store_request()}; // THROWING // handle exceptions that could arise during store_request if (!TlRpcError::transform_exception_into_error_if_possible().empty() || !static_cast(fetcher)) [[unlikely]] { return kphp::rpc::query_info{}; } - sp = rpc_server_instance_st.tl_storer.view().subspan(0, detail::RESERVED_HEADER_SIZE); - for (auto b : sp) { - if (b != static_cast(0)) { - kphp::log::error("BBB SERVER RESERVED HEADER BUFFER IS NOT ZEROED"); - } - } const auto query_info{kphp::rpc::send_request(actor, opt_timeout, ignore_answer, collect_responses_extra_info)}; if (!ignore_answer) { @@ -228,7 +213,6 @@ kphp::coro::task> rpc_tl_query_result_one_impl(int64_t query_id) no kphp::coro::task> typed_rpc_tl_query_result_one_impl(int64_t query_id, const RpcErrorFactory& error_factory) noexcept { if (query_id < kphp::rpc::VALID_QUERY_ID_RANGE_START) [[unlikely]] { - kphp::log::warning("--- A ---"); co_return error_factory.make_error(TL_ERROR_WRONG_QUERY_ID, string{"wrong query_id"}); } @@ -250,7 +234,6 @@ kphp::coro::task> typed_rpc_tl_query_result_ if (it_response_fetcher == rpc_client_instance_st.response_fetcher_instances.end() || it_fork_task == rpc_client_instance_st.response_awaiter_tasks.end()) [[unlikely]] { - kphp::log::warning("--- B ---"); co_return error_factory.make_error(TL_ERROR_INTERNAL, string{"unexpectedly could not find query in pending queries"}); } rpc_query = std::move(it_response_fetcher->second); @@ -258,22 +241,18 @@ kphp::coro::task> typed_rpc_tl_query_result_ } if (rpc_query.is_null()) [[unlikely]] { - kphp::log::warning("--- C ---"); co_return error_factory.make_error(TL_ERROR_INTERNAL, string{"can't use rpc_tl_query_result for non-TL query"}); } if (!rpc_query.get()->result_fetcher || rpc_query.get()->result_fetcher->empty()) [[unlikely]] { - kphp::log::warning("--- D ---"); co_return error_factory.make_error(TL_ERROR_INTERNAL, string{"rpc query has empty result fetcher"}); } if (!rpc_query.get()->result_fetcher->is_typed) [[unlikely]] { - kphp::log::warning("--- E ---"); co_return error_factory.make_error(TL_ERROR_INTERNAL, string{"can't get typed result from untyped TL query. Use consistent API for that"}); } kphp::log::assertion(opt_awaiter_task.has_value()); auto response_expected{co_await kphp::forks::id_managed(*std::exchange(opt_awaiter_task, std::nullopt))}; if (!response_expected) [[unlikely]] { - kphp::log::warning("--- F ---"); co_return error_factory.make_error(response_expected.error(), string{"can't fetch rpc response"}); } @@ -284,7 +263,6 @@ kphp::coro::task> typed_rpc_tl_query_result_ auto res{fetch_function_typed(rpc_query, error_factory)}; // THROWING // handle exceptions that could arise during fetch_function_typed if (auto err{error_factory.transform_exception_into_error_if_possible()}; !err.is_null()) [[unlikely]] { - kphp::log::warning("--- G ---"); co_return std::move(err); } co_return std::move(res); @@ -304,20 +282,6 @@ kphp::rpc::query_info send_request(std::string_view actor, std::optional // We do this to have enough place for regularized header after `kphp::rpc::regularize_extra_headers(...)` call. // This optimization helps us avoid allocating and copying the whole request. std::span request_buffer{rpc_server_instance_st.tl_storer.view().subspan(detail::RESERVED_HEADER_SIZE)}; - auto sp{rpc_server_instance_st.tl_storer.view().subspan(0, detail::RESERVED_HEADER_SIZE)}; - for (auto b : sp) { - if (b != static_cast(0)) { - kphp::log::error("C SERVER RESERVED HEADER BUFFER IS NOT ZEROED"); - } - } - tl::magic magic; - tl::fetcher debug_fetcherrr{request_buffer}; - kphp::log::assertion(magic.fetch(debug_fetcherrr)); - if (magic.value == TL_RPC_DEST_ACTOR) { - debug_fetcherrr = tl::fetcher{request_buffer.subspan(sizeof(kphp::rpc::dest_actor_header))}; - kphp::log::assertion(magic.fetch(debug_fetcherrr)); - // kphp::log::warning("request_buffer start op AFTER DEST ACTOR: {:x}", magic.value); - } if (const auto& [opt_new_extra_header, cur_extra_header_size]{kphp::rpc::regularize_extra_headers(request_buffer, ignore_answer)}; opt_new_extra_header) { std::span new_header{reinterpret_cast(std::addressof(*opt_new_extra_header)), @@ -336,63 +300,8 @@ kphp::rpc::query_info send_request(std::string_view actor, std::optional // we do always have enough bytes for `new_header` before `request_body`, because we have reserved it before `send_request(...)` call. size_t new_header_offset{detail::RESERVED_HEADER_SIZE + cur_extra_header_size - new_header.size()}; - - // kphp::log::warning("OPTIMIZATION SUCKS: {} - {} - {} - {} - {} - {} - {}", - // reinterpret_cast(rpc_server_instance_st.tl_storer.view().data()), - // reinterpret_cast(request_buffer.data()), - // reinterpret_cast(request_body.data()), - // detail::RESERVED_HEADER_SIZE, - // cur_extra_header_size, - // new_header.size(), - // reinterpret_cast(rpc_server_instance_st.tl_storer.view().subspan(new_header_offset).data())); - request_buffer = rpc_server_instance_st.tl_storer.view().subspan(new_header_offset); std::ranges::copy(new_header, request_buffer.data()); - - tl::magic magic; - tl::i64 actor_id{}; - tl::mask flags{}; - tl::rpcInvokeReqExtra extra{}; - // tl::magic op; - - tl::fetcher debug_fetcher{request_buffer}; - - kphp::log::assertion(magic.fetch(debug_fetcher)); - kphp::log::assertion(magic.expect(TL_RPC_DEST_ACTOR_FLAGS)); - - kphp::log::assertion(actor_id.fetch(debug_fetcher)); - kphp::log::assertion(actor_id.value == 0); - - kphp::log::assertion(flags.fetch(debug_fetcher)); - - // kphp::log::assertion(extra.fetch(debug_fetcher, flags)); - - // kphp::log::assertion(op.fetch(debug_fetcher)); - - // kphp::log::warning("REQUEST OP IS {:x}", op.value); - - } else { - - tl::fetcher debug_fetcher{request_buffer}; - - tl::magic magic; - - kphp::log::assertion(magic.fetch(debug_fetcher)); - - // bool was_dest_actor_header = false; - if (magic.expect(TL_RPC_DEST_ACTOR)) { - // was_dest_actor_header = true; - tl::i64 actor_id{}; - kphp::log::assertion(actor_id.fetch(debug_fetcher)); - - kphp::log::assertion(magic.fetch(debug_fetcher)); - } - - kphp::log::assertion(!magic.expect(TL_RPC_DEST_ACTOR_FLAGS)); - kphp::log::assertion(!magic.expect(TL_RPC_DEST_FLAGS)); - kphp::log::assertion(!magic.expect(TL_RPC_DEST_ACTOR)); - - // kphp::log::warning("request OP IS {:x} was_dest_actor_header({})", magic.value, was_dest_actor_header); } const size_t request_size{request_buffer.size_bytes()}; From c7c8f4b22c5555f37da122e0eb2d5b1197ef0baa Mon Sep 17 00:00:00 2001 From: Nikita Siniachenko Date: Mon, 24 Aug 2026 13:01:06 +0300 Subject: [PATCH 15/17] clearer comment --- runtime-light/stdlib/rpc/rpc-api.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/runtime-light/stdlib/rpc/rpc-api.cpp b/runtime-light/stdlib/rpc/rpc-api.cpp index 3ff445d7de..b8f6a06305 100644 --- a/runtime-light/stdlib/rpc/rpc-api.cpp +++ b/runtime-light/stdlib/rpc/rpc-api.cpp @@ -286,7 +286,8 @@ kphp::rpc::query_info send_request(std::string_view actor, std::optional if (const auto& [opt_new_extra_header, cur_extra_header_size]{kphp::rpc::regularize_extra_headers(request_buffer, ignore_answer)}; opt_new_extra_header) { std::span new_header{reinterpret_cast(std::addressof(*opt_new_extra_header)), sizeof(std::remove_cvref_t)}; - std::span request_body{request_buffer.subspan(cur_extra_header_size)}; + + // Let's name `request_body` as `request_buffer.subspan(cur_extra_header_size)}` // If `regularize_extra_headers` gave us new header, then we must serialize `new_header` before `request_body`. // @@ -298,7 +299,7 @@ kphp::rpc::query_info send_request(std::string_view actor, std::optional // // tl_storer will be: ... may be some bytes leaved here ... |our new header| |request-body| - // we do always have enough bytes for `new_header` before `request_body`, because we have reserved it before `send_request(...)` call. + // we do always have enough bytes for `new_header` before `request_body`, because we have reserved it in `f$rpc_clean(...)` call. size_t new_header_offset{detail::RESERVED_HEADER_SIZE + cur_extra_header_size - new_header.size()}; request_buffer = rpc_server_instance_st.tl_storer.view().subspan(new_header_offset); std::ranges::copy(new_header, request_buffer.data()); From 8bddd116ec564ba5773666c892ea20dcbd0d2933 Mon Sep 17 00:00:00 2001 From: Nikita Siniachenko Date: Mon, 24 Aug 2026 17:03:17 +0300 Subject: [PATCH 16/17] kphp::rpc::detail::clean_buffers() --- runtime-light/stdlib/rpc/rpc-api.cpp | 18 ++++++++++++++++++ runtime-light/stdlib/rpc/rpc-api.h | 14 ++------------ 2 files changed, 20 insertions(+), 12 deletions(-) diff --git a/runtime-light/stdlib/rpc/rpc-api.cpp b/runtime-light/stdlib/rpc/rpc-api.cpp index b8f6a06305..1af5b1a8b9 100644 --- a/runtime-light/stdlib/rpc/rpc-api.cpp +++ b/runtime-light/stdlib/rpc/rpc-api.cpp @@ -41,6 +41,24 @@ namespace kphp::rpc { namespace detail { +// store bytes for `kphp::rpc::dest_actor_flags_header` in RpcServerInstanceState::tl_storer. +// we do this to avoid allocating new buffer for regularized rpc extra headers and copying whole request. +void reserve_header() noexcept { + auto& rpc_server_instance_st{RpcServerInstanceState::get()}; + kphp::rpc::dest_actor_flags_header reserved_header{}; + static_assert(sizeof(reserved_header) == RESERVED_HEADER_SIZE); + rpc_server_instance_st.tl_storer.store_bytes({reinterpret_cast(std::addressof(reserved_header)), sizeof(reserved_header)}); +} + +void clean_buffers() noexcept { + auto& rpc_server_instance_st{RpcServerInstanceState::get()}; + rpc_server_instance_st.tl_storer.clear(); + kphp::rpc::detail::reserve_header(); + // TODO we need this just because we have one buffer for f$store_* functions and f$fetch_* functions. + // if we make another buffer for `rpc_server_instance_st.tl_fetcher`, then we don't need this. + rpc_server_instance_st.tl_fetcher = tl::fetcher{rpc_server_instance_st.tl_storer.view().subspan(kphp::rpc::detail::RESERVED_HEADER_SIZE)}; +} + mixed mixed_array_get_value(const mixed& arr, const string& str_key, int64_t num_key) noexcept { if (!arr.is_array()) [[unlikely]] { return {}; diff --git a/runtime-light/stdlib/rpc/rpc-api.h b/runtime-light/stdlib/rpc/rpc-api.h index 5f12175beb..313f231ed9 100644 --- a/runtime-light/stdlib/rpc/rpc-api.h +++ b/runtime-light/stdlib/rpc/rpc-api.h @@ -61,14 +61,7 @@ namespace detail { static constexpr size_t RESERVED_HEADER_SIZE{sizeof(kphp::rpc::dest_actor_flags_header)}; -// store bytes for `kphp::rpc::dest_actor_flags_header` in RpcServerInstanceState::tl_storer. -// we do this to avoid allocating new buffer for regularized rpc extra headers and copying whole request. -inline void reserve_header() noexcept { - auto& rpc_server_instance_st{RpcServerInstanceState::get()}; - kphp::rpc::dest_actor_flags_header reserved_header{}; - static_assert(sizeof(reserved_header) == RESERVED_HEADER_SIZE); - rpc_server_instance_st.tl_storer.store_bytes({reinterpret_cast(std::addressof(reserved_header)), sizeof(reserved_header)}); -} +void clean_buffers() noexcept; kphp::rpc::query_info rpc_tl_query_one_impl(std::string_view actor, const mixed& tl_object, std::optional opt_timeout, bool collect_resp_extra_info, bool ignore_answer) noexcept; @@ -209,10 +202,7 @@ inline void f$fetch_raw_vector_double(array& vector, int64_t num_elems) } inline bool f$rpc_clean() noexcept { - auto& rpc_server_instance_st{RpcServerInstanceState::get()}; - rpc_server_instance_st.tl_storer.clear(); - kphp::rpc::detail::reserve_header(); - rpc_server_instance_st.tl_fetcher = tl::fetcher{rpc_server_instance_st.tl_storer.view().subspan(kphp::rpc::detail::RESERVED_HEADER_SIZE)}; + kphp::rpc::detail::clean_buffers(); return true; } From 50f9522c10fb359cce6e51ac55fb9e6ae4b021b2 Mon Sep 17 00:00:00 2001 From: Nikita Siniachenko Date: Mon, 24 Aug 2026 22:19:48 +0300 Subject: [PATCH 17/17] clean_buffers() moved out from the details namespace --- runtime-light/stdlib/rpc/rpc-api.cpp | 18 +++++++++--------- runtime-light/stdlib/rpc/rpc-api.h | 6 +++--- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/runtime-light/stdlib/rpc/rpc-api.cpp b/runtime-light/stdlib/rpc/rpc-api.cpp index 1af5b1a8b9..5c573dc222 100644 --- a/runtime-light/stdlib/rpc/rpc-api.cpp +++ b/runtime-light/stdlib/rpc/rpc-api.cpp @@ -50,15 +50,6 @@ void reserve_header() noexcept { rpc_server_instance_st.tl_storer.store_bytes({reinterpret_cast(std::addressof(reserved_header)), sizeof(reserved_header)}); } -void clean_buffers() noexcept { - auto& rpc_server_instance_st{RpcServerInstanceState::get()}; - rpc_server_instance_st.tl_storer.clear(); - kphp::rpc::detail::reserve_header(); - // TODO we need this just because we have one buffer for f$store_* functions and f$fetch_* functions. - // if we make another buffer for `rpc_server_instance_st.tl_fetcher`, then we don't need this. - rpc_server_instance_st.tl_fetcher = tl::fetcher{rpc_server_instance_st.tl_storer.view().subspan(kphp::rpc::detail::RESERVED_HEADER_SIZE)}; -} - mixed mixed_array_get_value(const mixed& arr, const string& str_key, int64_t num_key) noexcept { if (!arr.is_array()) [[unlikely]] { return {}; @@ -288,6 +279,15 @@ kphp::coro::task> typed_rpc_tl_query_result_ } // namespace detail +void clean_buffers() noexcept { + auto& rpc_server_instance_st{RpcServerInstanceState::get()}; + rpc_server_instance_st.tl_storer.clear(); + kphp::rpc::detail::reserve_header(); + // TODO we need this just because we have one buffer for f$store_* functions and f$fetch_* functions. + // if we make another buffer for `rpc_server_instance_st.tl_fetcher`, then we don't need this. + rpc_server_instance_st.tl_fetcher = tl::fetcher{rpc_server_instance_st.tl_storer.view().subspan(kphp::rpc::detail::RESERVED_HEADER_SIZE)}; +} + kphp::rpc::query_info send_request(std::string_view actor, std::optional opt_timeout, bool ignore_answer, bool collect_responses_extra_info) noexcept { auto& rpc_client_instance_st{RpcClientInstanceState::get()}; auto& rpc_server_instance_st{RpcServerInstanceState::get()}; diff --git a/runtime-light/stdlib/rpc/rpc-api.h b/runtime-light/stdlib/rpc/rpc-api.h index 313f231ed9..fdef374024 100644 --- a/runtime-light/stdlib/rpc/rpc-api.h +++ b/runtime-light/stdlib/rpc/rpc-api.h @@ -61,8 +61,6 @@ namespace detail { static constexpr size_t RESERVED_HEADER_SIZE{sizeof(kphp::rpc::dest_actor_flags_header)}; -void clean_buffers() noexcept; - kphp::rpc::query_info rpc_tl_query_one_impl(std::string_view actor, const mixed& tl_object, std::optional opt_timeout, bool collect_resp_extra_info, bool ignore_answer) noexcept; @@ -75,6 +73,8 @@ kphp::coro::task> typed_rpc_tl_query_result_ } // namespace detail +void clean_buffers() noexcept; + } // namespace kphp::rpc // === server ===================================================================================== @@ -202,7 +202,7 @@ inline void f$fetch_raw_vector_double(array& vector, int64_t num_elems) } inline bool f$rpc_clean() noexcept { - kphp::rpc::detail::clean_buffers(); + kphp::rpc::clean_buffers(); return true; }