diff --git a/README.md b/README.md index 60f4c353d..9d325795e 100644 --- a/README.md +++ b/README.md @@ -185,7 +185,7 @@ std::vector buffer = struct_pack::serialize(person1); auto person2 = deserialize(buffer); ``` -struct_pack is very faster. +struct_pack is very fast. ![](https://alibaba.github.io/yalantinglibs/assets/struct_pack_bench_serialize.4ffb0ce6.png) diff --git a/include/ylt/coro_io/coro_io.hpp b/include/ylt/coro_io/coro_io.hpp index 058ffb730..d60b08f4d 100644 --- a/include/ylt/coro_io/coro_io.hpp +++ b/include/ylt/coro_io/coro_io.hpp @@ -25,6 +25,7 @@ #endif #include +#include #include #include #include @@ -282,20 +283,42 @@ inline async_simple::coro::Lazy sleep_for(Duration d) { } } -template -inline async_simple::coro::Lazy post( - Func func, - coro_io::ExecutorWrapper<> *e = coro_io::get_global_block_executor()) { - callback_awaitor awaitor; - - co_return co_await awaitor.await_resume( - [e, func = std::move(func)](auto handler) { - auto executor = e->get_asio_executor(); - asio::post(executor, [=, func = std::move(func)]() { +template +struct post_helper { + void operator()(auto handler) const { + asio::dispatch(e->get_asio_executor(), [this, handler]() { + try { + if constexpr (std::is_same_v>) { func(); handler.resume(); - }); - }); + } + else { + auto r = func(); + handler.set_value_then_resume(std::move(r)); + } + } catch (const std::exception &e) { + R er; + er.setException(std::current_exception()); + handler.set_value_then_resume(std::move(er)); + } + }); + } + coro_io::ExecutorWrapper<> *e; + Func func; +}; + +template +inline async_simple::coro::Lazy< + async_simple::Try::return_type>> +post(Func func, + coro_io::ExecutorWrapper<> *e = coro_io::get_global_block_executor()) { + using R = + async_simple::Try::return_type>; + + callback_awaitor awaitor; + + post_helper helper{e, std::move(func)}; + co_return co_await awaitor.await_resume(helper); } template diff --git a/include/ylt/coro_rpc/impl/context.hpp b/include/ylt/coro_rpc/impl/context.hpp index d9f1e6d5a..b4748b10e 100644 --- a/include/ylt/coro_rpc/impl/context.hpp +++ b/include/ylt/coro_rpc/impl/context.hpp @@ -159,8 +159,9 @@ struct get_type_t> { template inline auto get_return_type() { using T = decltype(func); - using param_type = function_parameters_t; - using return_type = typename get_type_t>::type; + using param_type = util::function_parameters_t; + using return_type = + typename get_type_t>::type; if constexpr (std::is_void_v) { if constexpr (std::is_void_v) { return; @@ -171,7 +172,8 @@ inline auto get_return_type() { } else { using First = std::tuple_element_t<0, param_type>; - constexpr bool is_conn = is_specialization::value; + constexpr bool is_conn = + util::is_specialization::value; if constexpr (is_conn) { using U = typename First::return_type; diff --git a/include/ylt/coro_rpc/impl/coro_rpc_client.hpp b/include/ylt/coro_rpc/impl/coro_rpc_client.hpp index 2a8bda43b..1a7529f45 100644 --- a/include/ylt/coro_rpc/impl/coro_rpc_client.hpp +++ b/include/ylt/coro_rpc/impl/coro_rpc_client.hpp @@ -486,41 +486,42 @@ class coro_rpc_client { template void static_check() { using Function = decltype(func); - using param_type = function_parameters_t; + using param_type = util::function_parameters_t; if constexpr (!std::is_void_v) { using First = std::tuple_element_t<0, param_type>; constexpr bool is_conn = requires { typename First::return_type; }; if constexpr (std::is_member_function_pointer_v) { - using Self = class_type_t; + using Self = util::class_type_t; if constexpr (is_conn) { - static_assert(is_invocable::value, - "called rpc function and arguments are not match"); + static_assert( + util::is_invocable::value, + "called rpc function and arguments are not match"); } else { - static_assert(is_invocable::value, + static_assert(util::is_invocable::value, "called rpc function and arguments are not match"); } } else { if constexpr (is_conn) { - static_assert(is_invocable::value, + static_assert(util::is_invocable::value, "called rpc function and arguments are not match"); } else { - static_assert(is_invocable::value, + static_assert(util::is_invocable::value, "called rpc function and arguments are not match"); } } } else { if constexpr (std::is_member_function_pointer_v) { - using Self = class_type_t; - static_assert(is_invocable::value, + using Self = util::class_type_t; + static_assert(util::is_invocable::value, "called rpc function and arguments are not match"); } else { - static_assert(is_invocable::value, + static_assert(util::is_invocable::value, "called rpc function and arguments are not match"); } } @@ -661,7 +662,7 @@ class coro_rpc_client { std::vector buffer; std::size_t offset = coro_rpc_protocol::REQ_HEAD_LEN; if constexpr (sizeof...(Args) > 0) { - using arg_types = function_parameters_t; + using arg_types = util::function_parameters_t; pack_to(buffer, offset, std::forward(args)...); } else { @@ -723,7 +724,7 @@ class coro_rpc_client { auto get_func_args() { using First = std::tuple_element_t<0, FuncArgs>; constexpr bool has_conn_v = requires { typename First::return_type; }; - return get_args(); + return util::get_args(); } template diff --git a/include/ylt/coro_rpc/impl/coro_rpc_server.hpp b/include/ylt/coro_rpc/impl/coro_rpc_server.hpp index ccd6d0b29..9786912e3 100644 --- a/include/ylt/coro_rpc/impl/coro_rpc_server.hpp +++ b/include/ylt/coro_rpc/impl/coro_rpc_server.hpp @@ -236,12 +236,13 @@ class coro_rpc_server_base { */ template - void register_handler(class_type_t *self) { + void register_handler(util::class_type_t *self) { router_.template register_handler(self); } template - void register_handler(class_type_t *self, const auto &key) { + void register_handler(util::class_type_t *self, + const auto &key) { router_.template register_handler(self, key); } diff --git a/include/ylt/coro_rpc/impl/router.hpp b/include/ylt/coro_rpc/impl/router.hpp index c28f361ce..0e85aa96d 100644 --- a/include/ylt/coro_rpc/impl/router.hpp +++ b/include/ylt/coro_rpc/impl/router.hpp @@ -127,8 +127,9 @@ class router { AS_UNLIKELY { ELOGV(CRITICAL, "null connection!"); } constexpr auto name = get_func_name(); - using return_type = function_return_type_t; - if constexpr (is_specialization_v) { + using return_type = util::function_return_type_t; + if constexpr (util::is_specialization_v) { auto it = coro_handlers_.emplace( key, [self]( @@ -179,10 +180,11 @@ class router { void regist_one_handler_impl(const route_key &key) { static_assert(!std::is_member_function_pointer_v, "register member function but lack of the parent object"); - using return_type = function_return_type_t; + using return_type = util::function_return_type_t; constexpr auto name = get_func_name(); - if constexpr (is_specialization_v) { + if constexpr (util::is_specialization_v) { auto it = coro_handlers_.emplace( key, [](std::string_view data, rpc_context &context_info, @@ -350,13 +352,13 @@ class router { */ template - void register_handler(class_type_t *self) { + void register_handler(util::class_type_t *self) { regist_one_handler(self); (regist_one_handler(self), ...); } template - void register_handler(class_type_t *self, + void register_handler(util::class_type_t *self, const route_key &key) { regist_one_handler_impl(self, key); } diff --git a/include/ylt/coro_rpc/impl/rpc_execute.hpp b/include/ylt/coro_rpc/impl/rpc_execute.hpp index 1c0223e08..0a93a2338 100644 --- a/include/ylt/coro_rpc/impl/rpc_execute.hpp +++ b/include/ylt/coro_rpc/impl/rpc_execute.hpp @@ -54,8 +54,8 @@ inline std::optional execute( std::string_view data, rpc_context &context_info, Self *self = nullptr) { using T = decltype(func); - using param_type = function_parameters_t; - using return_type = function_return_type_t; + using param_type = util::function_parameters_t; + using return_type = util::function_return_type_t; if constexpr (!std::is_void_v) { using First = std::tuple_element_t<0, param_type>; @@ -69,7 +69,7 @@ inline std::optional execute( constexpr bool has_coro_conn_v = std::is_convertible_v, First>; - auto args = get_args(); + auto args = util::get_args(); bool is_ok = true; constexpr size_t size = std::tuple_size_v; @@ -155,9 +155,9 @@ inline async_simple::coro::Lazy> execute_coro( std::string_view data, rpc_context &context_info, Self *self = nullptr) { using T = decltype(func); - using param_type = function_parameters_t; - using return_type = - typename get_type_t::ValueType>::type; + using param_type = util::function_parameters_t; + using return_type = typename get_type_t< + typename util::function_return_type_t::ValueType>::type; if constexpr (!std::is_void_v) { using First = std::tuple_element_t<0, param_type>; @@ -170,7 +170,7 @@ inline async_simple::coro::Lazy> execute_coro( using conn_return_type = decltype(get_return_type()); constexpr bool has_coro_conn_v = std::is_same_v, First>; - auto args = get_args(); + auto args = util::get_args(); bool is_ok = true; constexpr size_t size = std::tuple_size_v; diff --git a/include/ylt/util/type_traits.h b/include/ylt/util/type_traits.h index 6dabf57b2..15b1ad768 100644 --- a/include/ylt/util/type_traits.h +++ b/include/ylt/util/type_traits.h @@ -30,7 +30,7 @@ using remove_cvref_t = typename remove_cvref::type; #endif #endif -namespace coro_rpc { +namespace util { template struct function_traits; @@ -213,4 +213,4 @@ struct is_specialization, Ref> : std::true_type {}; template class Ref> inline constexpr bool is_specialization_v = is_specialization::value; -} // namespace coro_rpc +} // namespace util diff --git a/src/coro_rpc/tests/test_coro_rpc_client.cpp b/src/coro_rpc/tests/test_coro_rpc_client.cpp index 19653f188..4aee088cb 100644 --- a/src/coro_rpc/tests/test_coro_rpc_client.cpp +++ b/src/coro_rpc/tests/test_coro_rpc_client.cpp @@ -478,6 +478,7 @@ TEST_CASE("testing client call timeout") { CHECK_MESSAGE(val.error().code == std::errc::timed_out, val.error().msg); g_action = inject_action::nothing; } +#ifdef __GNUC__ SUBCASE("read timeout") { g_action = {}; coro_rpc_server server(2, 8801); @@ -494,6 +495,7 @@ TEST_CASE("testing client call timeout") { auto val = syncAwait(ret); CHECK_MESSAGE(val.error().code == std::errc::timed_out, val.error().msg); } +#endif g_action = {}; } std::errc init_acceptor(auto& acceptor_, auto port_) { diff --git a/src/coro_rpc/tests/test_router.cpp b/src/coro_rpc/tests/test_router.cpp index b72f50505..96636f12b 100644 --- a/src/coro_rpc/tests/test_router.cpp +++ b/src/coro_rpc/tests/test_router.cpp @@ -66,12 +66,12 @@ struct RPC_trait { }; using coro_rpc_protocol = coro_rpc::protocol::coro_rpc_protocol; template -rpc_result, coro_rpc_protocol> +rpc_result, coro_rpc_protocol> get_result(const auto &pair) { auto &&[rpc_errc, buffer] = pair; - using T = function_return_type_t; - using return_type = - rpc_result, coro_rpc_protocol>; + using T = util::function_return_type_t; + using return_type = rpc_result, + coro_rpc_protocol>; rpc_return_type_t ret; struct_pack::errc ec; coro_rpc_protocol::rpc_error err; @@ -144,7 +144,7 @@ auto test_route(auto ctx, Args &&...args) { template void test_route_and_check(auto conn, Args &&...args) { auto pair = test_route(conn, std::forward(args)...); - using R = function_return_type_t; + using R = util::function_return_type_t; check_result(pair, coro_rpc_protocol::RESP_HEAD_LEN); } } // namespace test_util diff --git a/src/util/tests/test_meta_string.cpp b/src/util/tests/test_meta_string.cpp index 0613f6c96..79324fa6c 100644 --- a/src/util/tests/test_meta_string.cpp +++ b/src/util/tests/test_meta_string.cpp @@ -167,7 +167,7 @@ struct Plus { }; constexpr void function_traits_test_return_type() { - using namespace coro_rpc; + using namespace util; static_assert(std::is_same_v, int>); auto f1 = []() { }; @@ -208,7 +208,7 @@ constexpr void function_traits_test_return_type() { } constexpr void function_traits_test_last_parameters_type() { - using namespace coro_rpc; + using namespace util; static_assert(std::is_same_v, int>); auto f1 = [](int&) { }; diff --git a/website/docs/zh/coro_rpc/coro_rpc_doc.hpp b/website/docs/zh/coro_rpc/coro_rpc_doc.hpp index 57b370cdf..4f7dd8e44 100644 --- a/website/docs/zh/coro_rpc/coro_rpc_doc.hpp +++ b/website/docs/zh/coro_rpc/coro_rpc_doc.hpp @@ -135,7 +135,7 @@ class coro_rpc_server { * @param self 成员函数对应的对象指针 */ template - void register_handler(class_type_t *self); + void register_handler(util::class_type_t *self); }; /*! @@ -229,7 +229,8 @@ class coro_rpc_client { * @return rpc调用结果 */ template - async_simple::coro::Lazy>> + async_simple::coro::Lazy< + rpc_result>> call(Args &&...args); /*! @@ -241,7 +242,8 @@ class coro_rpc_client { * @return rpc调用结果 */ template - async_simple::coro::Lazy>> + async_simple::coro::Lazy< + rpc_result>> call_for(const auto &duration, Args &&...args); /*!