Aedis 1.4.1
A redis client library
common.cpp
1/* Copyright (c) 2018-2022 Marcelo Zimbres Silva (mzimbres@gmail.com)
2 *
3 * Distributed under the Boost Software License, Version 1.0. (See
4 * accompanying file LICENSE.txt)
5 */
6
7#include "common.hpp"
8
9#include <boost/asio.hpp>
10#if defined(BOOST_ASIO_HAS_CO_AWAIT)
11#include <boost/asio/experimental/awaitable_operators.hpp>
12#include <iostream>
13
14namespace net = boost::asio;
15using namespace net::experimental::awaitable_operators;
16using resolver = net::use_awaitable_t<>::as_default_on_t<net::ip::tcp::resolver>;
17using timer_type = net::use_awaitable_t<>::as_default_on_t<net::steady_timer>;
19using aedis::adapt;
21
22namespace
23{
24auto redir(boost::system::error_code& ec)
25 { return net::redirect_error(net::use_awaitable, ec); }
26}
27
28auto healthy_checker(std::shared_ptr<connection> conn) -> net::awaitable<void>
29{
30 try {
31 request req;
32 req.push("PING");
33
34 timer_type timer{co_await net::this_coro::executor};
35
36 for (boost::system::error_code ec;;) {
37 timer.expires_after(std::chrono::seconds{1});
38 co_await (conn->async_exec(req, adapt()) || timer.async_wait(redir(ec)));
39
40 if (!ec) {
41 co_return;
42 }
43
44 // Waits some time before trying the next ping.
45 timer.expires_after(std::chrono::seconds{1});
46 co_await timer.async_wait();
47 }
48 } catch (...) {
49 }
50}
51
52auto
53connect(
54 std::shared_ptr<connection> conn,
55 std::string const& host,
56 std::string const& port) -> net::awaitable<void>
57{
58 auto ex = co_await net::this_coro::executor;
59 resolver resv{ex};
60 timer_type timer{ex};
61
62 boost::system::error_code ec;
63 timer.expires_after(std::chrono::seconds{5});
64 auto const addrs = co_await (resv.async_resolve(host, port) || timer.async_wait(redir(ec)));
65 if (!ec)
66 throw std::runtime_error("Resolve timeout");
67
68 timer.expires_after(std::chrono::seconds{5});
69 co_await (net::async_connect(conn->next_layer(), std::get<0>(addrs)) || timer.async_wait(redir(ec)));
70 if (!ec)
71 throw std::runtime_error("Connect timeout");
72}
73
74auto run(net::awaitable<void> op) -> int
75{
76 try {
77 net::io_context ioc;
78 net::co_spawn(ioc, std::move(op), [](std::exception_ptr p) {
79 if (p)
80 std::rethrow_exception(p);
81 });
82 ioc.run();
83
84 return 0;
85
86 } catch (std::exception const& e) {
87 std::cerr << "Error: " << e.what() << std::endl;
88 }
89
90 return 1;
91}
92
93#endif // defined(BOOST_ASIO_HAS_CO_AWAIT)
Creates Redis requests.
Definition: request.hpp:169
auto adapt(std::size_t max_read_size=(std::numeric_limits< std::size_t >::max)()) noexcept
Creates an adapter that ignores responses.
Definition: adapt.hpp:199
operation
Connection operations that can be cancelled.
Definition: operation.hpp:18
@ run
Refers to connection::async_run operations.