/* Copyright (c) 2018-2022 Marcelo Zimbres Silva (mzimbres@gmail.com) * * Distributed under the Boost Software License, Version 1.0. (See * accompanying file LICENSE.txt) */ #include "common.hpp" #if defined(BOOST_ASIO_HAS_CO_AWAIT) #include #include namespace net = boost::asio; using namespace net::experimental::awaitable_operators; using resolver = net::use_awaitable_t<>::as_default_on_t; using timer_type = net::use_awaitable_t<>::as_default_on_t; using aedis::resp3::request; using aedis::adapt; using aedis::operation; // Include this in no more than one .cpp file. #include namespace { auto redir(boost::system::error_code& ec) { return net::redirect_error(net::use_awaitable, ec); } } auto healthy_checker(std::shared_ptr conn) -> net::awaitable { try { request req; req.get_config().cancel_on_connection_lost = true; req.push("PING"); timer_type timer{co_await net::this_coro::executor}; for (boost::system::error_code ec;;) { timer.expires_after(std::chrono::seconds{1}); co_await (conn->async_exec(req, adapt()) || timer.async_wait(redir(ec))); if (!ec) { co_return; } // Waits some time before trying the next ping. timer.expires_after(std::chrono::seconds{1}); co_await timer.async_wait(); } } catch (...) { } } auto connect( std::shared_ptr conn, std::string const& host, std::string const& port) -> net::awaitable { auto ex = co_await net::this_coro::executor; resolver resv{ex}; timer_type timer{ex}; boost::system::error_code ec; timer.expires_after(std::chrono::seconds{5}); auto const addrs = co_await (resv.async_resolve(host, port) || timer.async_wait(redir(ec))); if (!ec) throw std::runtime_error("Resolve timeout"); timer.expires_after(std::chrono::seconds{5}); co_await (net::async_connect(conn->next_layer(), std::get<0>(addrs)) || timer.async_wait(redir(ec))); if (!ec) throw std::runtime_error("Connect timeout"); } extern net::awaitable async_main(); // Main function used in our examples. auto main() -> int { try { net::io_context ioc; net::co_spawn(ioc, async_main(), net::detached); ioc.run(); } catch (std::exception const& e) { std::cerr << "Error: " << e.what() << std::endl; return 1; } } #else // defined(BOOST_ASIO_HAS_CO_AWAIT) auto main() -> int {std::cout << "Requires coroutine support." << std::endl; return 0;} #endif // defined(BOOST_ASIO_HAS_CO_AWAIT)