From 76b6106caa3f8db1ed4474073164ceb4f05d6e1f Mon Sep 17 00:00:00 2001 From: Marcelo Zimbres Date: Sat, 16 Jul 2022 21:21:13 +0200 Subject: [PATCH] Fixes executor usage in connection class. --- aedis/connection.hpp | 20 ++++++++++-------- aedis/detail/net.hpp | 24 ++++++++++++++-------- benchmarks/cpp/asio/echo_server_direct.cpp | 24 +++++++++++++--------- examples/echo_server.cpp | 14 ++++++++----- 4 files changed, 51 insertions(+), 31 deletions(-) diff --git a/aedis/connection.hpp b/aedis/connection.hpp index e28300c6..5d45ca77 100644 --- a/aedis/connection.hpp +++ b/aedis/connection.hpp @@ -69,7 +69,7 @@ public: * \param ex The executor. * \param cfg Configuration parameters. */ - connection(boost::asio::any_io_executor ex, config cfg = config{}) + connection(executor_type ex, config cfg = config{}) : resv_{ex} , ping_timer_{ex} , check_idle_timer_{ex} @@ -299,7 +299,7 @@ public: private: struct req_info { - req_info(boost::asio::any_io_executor ex) : timer{ex} {} + req_info(executor_type ex) : timer{ex} {} boost::asio::steady_timer timer; resp3::request const* req = nullptr; std::size_t cmds = 0; @@ -440,15 +440,19 @@ private: } } - using channel_type = boost::asio::experimental::channel; + using channel_type = boost::asio::experimental::channel; + using clock_type = std::chrono::steady_clock; + using clock_traits_type = boost::asio::wait_traits; + using timer_type = boost::asio::basic_waitable_timer; + using resolver_type = boost::asio::ip::basic_resolver; // IO objects - boost::asio::ip::tcp::resolver resv_; + resolver_type resv_; std::shared_ptr socket_; - boost::asio::steady_timer ping_timer_; - boost::asio::steady_timer check_idle_timer_; - boost::asio::steady_timer writer_timer_; - boost::asio::steady_timer read_timer_; + timer_type ping_timer_; + timer_type check_idle_timer_; + timer_type writer_timer_; + timer_type read_timer_; channel_type push_channel_; config cfg_; diff --git a/aedis/detail/net.hpp b/aedis/detail/net.hpp index dfc5e80e..fe7e374e 100644 --- a/aedis/detail/net.hpp +++ b/aedis/detail/net.hpp @@ -18,6 +18,9 @@ namespace aedis { namespace detail { +template +using conn_timer_t = boost::asio::basic_waitable_timer, Executor>; + #include template < @@ -27,7 +30,7 @@ template < > struct connect_op { boost::asio::basic_socket* socket; - boost::asio::steady_timer* timer; + conn_timer_t* timer; EndpointSequence* endpoints; boost::asio::coroutine coro; @@ -77,9 +80,10 @@ struct connect_op { } }; +template struct resolve_op { - boost::asio::ip::tcp::resolver* resv; - boost::asio::steady_timer* timer; + Resolver* resv; + Timer* timer; boost::string_view host; boost::string_view port; boost::asio::coroutine coro; @@ -160,7 +164,7 @@ template < > auto async_connect( boost::asio::basic_socket& socket, - boost::asio::steady_timer& timer, + conn_timer_t& timer, EndpointSequence ep, CompletionToken&& token = boost::asio::default_completion_token_t{}) { @@ -172,20 +176,24 @@ auto async_connect( } template < + class Resolver, + class Timer, class CompletionToken = - boost::asio::default_completion_token_t + boost::asio::default_completion_token_t > auto async_resolve( - boost::asio::ip::tcp::resolver& resv, - boost::asio::steady_timer& timer, + Resolver& resv, + Timer& timer, boost::string_view host, boost::string_view port, CompletionToken&& token = CompletionToken{}) { + // TODO: Use static_assert to check Resolver::executor_type and + // Timer::executor_type are same. return boost::asio::async_compose < CompletionToken , void(boost::system::error_code, boost::asio::ip::tcp::resolver::results_type) - >(resolve_op{&resv, &timer, host, port}, token, resv, timer); + >(resolve_op{&resv, &timer, host, port}, token, resv, timer); } template < diff --git a/benchmarks/cpp/asio/echo_server_direct.cpp b/benchmarks/cpp/asio/echo_server_direct.cpp index 9fe55d97..90ce337d 100644 --- a/benchmarks/cpp/asio/echo_server_direct.cpp +++ b/benchmarks/cpp/asio/echo_server_direct.cpp @@ -19,12 +19,16 @@ namespace net = boost::asio; namespace this_coro = net::this_coro; using net::ip::tcp; -using net::awaitable; -using net::co_spawn; using net::detached; -using net::use_awaitable; +using executor_type = net::io_context::executor_type; +using socket_type = net::basic_stream_socket; +using tcp_socket = net::use_awaitable_t::as_default_on_t; +using acceptor_type = net::basic_socket_acceptor; +using tcp_acceptor = net::use_awaitable_t::as_default_on_t; +using awaitable_type = net::awaitable; +constexpr net::use_awaitable_t use_awaitable; -awaitable echo(tcp::socket socket) +awaitable_type echo(tcp_socket socket) { try { char data[1024]; @@ -37,20 +41,20 @@ awaitable echo(tcp::socket socket) } } -awaitable listener() +awaitable_type listener() { - auto executor = co_await this_coro::executor; - tcp::acceptor acceptor(executor, {tcp::v4(), 55555}); + auto ex = co_await this_coro::executor; + tcp_acceptor acceptor(ex, {tcp::v4(), 55555}); for (;;) { - tcp::socket socket = co_await acceptor.async_accept(use_awaitable); - co_spawn(executor, echo(std::move(socket)), detached); + tcp_socket socket = co_await acceptor.async_accept(use_awaitable); + co_spawn(ex, echo(std::move(socket)), detached); } } int main() { try { - net::io_context io_context(1); + net::io_context io_context{BOOST_ASIO_CONCURRENCY_HINT_UNSAFE_IO}; co_spawn(io_context, listener(), detached); io_context.run(); } catch (std::exception const& e) { diff --git a/examples/echo_server.cpp b/examples/echo_server.cpp index 85e0f8d2..9701ea6b 100644 --- a/examples/echo_server.cpp +++ b/examples/echo_server.cpp @@ -16,11 +16,15 @@ namespace net = boost::asio; using aedis::adapt; using aedis::resp3::request; -using tcp_socket = net::use_awaitable_t<>::as_default_on_t; -using tcp_acceptor = net::use_awaitable_t<>::as_default_on_t; +using executor_type = net::io_context::executor_type; +using socket_type = net::basic_stream_socket; +using tcp_socket = net::use_awaitable_t::as_default_on_t; +using acceptor_type = net::basic_socket_acceptor; +using tcp_acceptor = net::use_awaitable_t::as_default_on_t; +using awaitable_type = net::awaitable; using connection = aedis::connection; -net::awaitable echo_loop(tcp_socket socket, std::shared_ptr db) +awaitable_type echo_loop(tcp_socket socket, std::shared_ptr db) { try { request req; @@ -41,7 +45,7 @@ net::awaitable echo_loop(tcp_socket socket, std::shared_ptr db } } -net::awaitable listener() +awaitable_type listener() { auto ex = co_await net::this_coro::executor; auto db = std::make_shared(ex); @@ -59,7 +63,7 @@ net::awaitable listener() int main() { try { - net::io_context ioc; + net::io_context ioc{BOOST_ASIO_CONCURRENCY_HINT_UNSAFE_IO}; co_spawn(ioc, listener(), net::detached); ioc.run(); } catch (std::exception const& e) {