Skip to content

Commit dc9b333

Browse files
committed
Passes timeouts as parameters to async_run.
1 parent dac7bea commit dc9b333

20 files changed

+268
-207
lines changed

examples/chat_room.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ net::awaitable<void> reconnect(std::shared_ptr<connection> db)
5454
endpoint ep{"127.0.0.1", "6379"};
5555
for (;;) {
5656
boost::system::error_code ec;
57-
co_await db->async_run(ep, req, adapt(), net::redirect_error(net::use_awaitable, ec));
57+
co_await db->async_run(ep, req, adapt(), {}, net::redirect_error(net::use_awaitable, ec));
5858
db->reset_stream();
5959
std::cout << ec.message() << std::endl;
6060
timer.expires_after(std::chrono::seconds{1});

examples/containers.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ auto main() -> int
5050
net::io_context ioc;
5151
connection db{ioc};
5252
endpoint ep{"127.0.0.1", "6379"};
53-
db.async_run(ep, req, adapt(resp), [](auto ec, auto) {
53+
db.async_run(ep, req, adapt(resp), {}, [](auto ec, auto) {
5454
std::cout << ec.message() << std::endl;
5555
});
5656
ioc.run();

examples/echo_server.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ auto main() -> int
5656
net::io_context ioc{BOOST_ASIO_CONCURRENCY_HINT_UNSAFE_IO};
5757
auto db = std::make_shared<connection>(ioc);
5858
endpoint ep{"127.0.0.1", "6379"};
59-
db->async_run(ep, [&](auto const& ec) {
59+
db->async_run(ep, {}, [&](auto const& ec) {
6060
std::clog << ec.message() << std::endl;
6161
ioc.stop();
6262
});

examples/intro.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ auto main() -> int
3030
req.push("QUIT");
3131

3232
std::tuple<std::string, aedis::ignore> resp;
33-
db.async_run({"127.0.0.1", "6379"}, req, adapt(resp), [](auto ec, auto) {
33+
db.async_run({"127.0.0.1", "6379"}, req, adapt(resp), {}, [](auto ec, auto) {
3434
std::cout << ec.message() << std::endl;
3535
});
3636

examples/intro_sync.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ int main()
3838

3939
connection conn{ioc};
4040
std::thread t{[&]() {
41-
conn.async_run({"127.0.0.1", "6379"}, logger);
41+
conn.async_run({"127.0.0.1", "6379"}, {}, logger);
4242
ioc.run();
4343
}};
4444

examples/intro_tls.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ auto main() -> int
4242
req.push("QUIT");
4343

4444
std::tuple<std::string, aedis::ignore> resp;
45-
conn.async_run({"127.0.0.1", "6379"}, req, adapt(resp), [&](auto ec, auto) {
45+
conn.async_run({"127.0.0.1", "6379"}, req, adapt(resp), {}, [&](auto ec, auto) {
4646
std::cout << ec.message() << std::endl;
4747
});
4848

examples/serialization.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ int main()
100100
std::tuple<aedis::ignore, int, std::set<user>, std::string> resp;
101101

102102
endpoint ep{"127.0.0.1", "6379"};
103-
db.async_run(ep, req, adapt(resp), [](auto ec, auto) {
103+
db.async_run(ep, req, adapt(resp), {}, [](auto ec, auto) {
104104
std::cout << ec.message() << std::endl;
105105
});
106106

examples/subscriber.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ net::awaitable<void> reconnect(std::shared_ptr<connection> db)
6464
endpoint ep{"127.0.0.1", "6379"};
6565
for (;;) {
6666
boost::system::error_code ec;
67-
co_await db->async_run(ep, req, adapt(), net::redirect_error(net::use_awaitable, ec));
67+
co_await db->async_run(ep, req, adapt(), {}, net::redirect_error(net::use_awaitable, ec));
6868
db->reset_stream();
6969
std::cout << ec.message() << std::endl;
7070
timer.expires_after(std::chrono::seconds{1});

examples/subscriber_sentinel.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ net::awaitable<endpoint> resolve()
6060
std::tuple<std::optional<std::array<std::string, 2>>, aedis::ignore> addr;
6161
for (auto ep : endpoints) {
6262
boost::system::error_code ec;
63-
co_await conn.async_run(ep, req1, adapt(addr), net::redirect_error(net::use_awaitable, ec));
63+
co_await conn.async_run(ep, req1, adapt(addr), {}, net::redirect_error(net::use_awaitable, ec));
6464
conn.reset_stream();
6565
std::cout << ec.message() << std::endl;
6666
if (std::get<0>(addr))
@@ -91,7 +91,7 @@ net::awaitable<void> reconnect(std::shared_ptr<connection> db)
9191
}
9292

9393
boost::system::error_code ec;
94-
co_await db->async_run(ep, req2, adapt(), net::redirect_error(net::use_awaitable, ec));
94+
co_await db->async_run(ep, req2, adapt(), {}, net::redirect_error(net::use_awaitable, ec));
9595
std::cout << ec.message() << std::endl;
9696
std::cout << "Starting the failover." << std::endl;
9797
timer.expires_after(std::chrono::seconds{1});

include/aedis/connection.hpp

+101-18
Original file line numberDiff line numberDiff line change
@@ -43,37 +43,30 @@ class connection :
4343

4444
/** @brief Connection configuration parameters.
4545
*/
46-
struct config {
46+
struct timeouts {
4747
/// Timeout of the resolve operation.
48-
std::chrono::milliseconds resolve_timeout = std::chrono::seconds{10};
48+
std::chrono::steady_clock::duration resolve_timeout = std::chrono::seconds{10};
4949

5050
/// Timeout of the connect operation.
51-
std::chrono::milliseconds connect_timeout = std::chrono::seconds{10};
51+
std::chrono::steady_clock::duration connect_timeout = std::chrono::seconds{10};
5252

5353
/// Timeout of the resp3 handshake operation.
54-
std::chrono::milliseconds resp3_handshake_timeout = std::chrono::seconds{2};
54+
std::chrono::steady_clock::duration resp3_handshake_timeout = std::chrono::seconds{2};
5555

5656
/// Time interval of ping operations.
57-
std::chrono::milliseconds ping_interval = std::chrono::seconds{1};
57+
std::chrono::steady_clock::duration ping_interval = std::chrono::seconds{1};
5858
};
5959

6060
/// Constructor
61-
explicit connection(executor_type ex, config cfg = {})
61+
explicit connection(executor_type ex)
6262
: base_type{ex}
63-
, cfg_{cfg}
6463
, stream_{ex}
6564
{}
6665

67-
explicit connection(boost::asio::io_context& ioc, config cfg = config{})
68-
: connection(ioc.get_executor(), std::move(cfg))
66+
explicit connection(boost::asio::io_context& ioc)
67+
: connection(ioc.get_executor())
6968
{ }
7069

71-
/// Returns a reference to the configuration parameters.
72-
auto get_config() noexcept -> config& { return cfg_;}
73-
74-
/// Returns a const reference to the configuration parameters.
75-
auto get_config() const noexcept -> config const& { return cfg_;}
76-
7770
/// Resets the underlying stream.
7871
void reset_stream()
7972
{
@@ -90,6 +83,97 @@ class connection :
9083
/// Returns a const reference to the next layer.
9184
auto next_layer() const noexcept -> auto const& { return stream_; }
9285

86+
/** @brief Starts communication with the Redis server asynchronously.
87+
*
88+
* This function performs the following steps
89+
*
90+
* @li Resolves the Redis host as of `async_resolve` with the
91+
* timeout passed in the base class `connection::timeouts::resolve_timeout`.
92+
*
93+
* @li Connects to one of the endpoints returned by the resolve
94+
* operation with the timeout passed in the base class
95+
* `connection::timeouts::connect_timeout`.
96+
*
97+
* @li Performs a RESP3 handshake by sending a
98+
* [HELLO](https://redis.io/commands/hello/) command with protocol
99+
* version 3 and the credentials contained in the
100+
* `aedis::endpoint` object. The timeout used is the one specified
101+
* in `connection::timeouts::resp3_handshake_timeout`.
102+
*
103+
* @li Erases any password that may be contained in
104+
* `endpoint::password`.
105+
*
106+
* @li Checks whether the server role corresponds to the one
107+
* specifed in the `endpoint`. If `endpoint::role` is left empty,
108+
* no check is performed. If the role role is different than the
109+
* expected `async_run` will complete with
110+
* `error::unexpected_server_role`.
111+
*
112+
* @li Starts healthy checks with a timeout twice the value of
113+
* `connection::timeouts::ping_interval`. If no data is received during that
114+
* time interval `connection::async_run` completes with
115+
* `error::idle_timeout`.
116+
*
117+
* @li Starts the healthy check operation that sends the
118+
* [PING](https://redis.io/commands/ping/) to Redis with a
119+
* frequency equal to `connection::timeouts::ping_interval`.
120+
*
121+
* @li Starts reading from the socket and executes all requests
122+
* that have been started prior to this function call.
123+
*
124+
* @param ep Redis endpoint.
125+
* @param ts Timeouts used by the operations.
126+
* @param token Completion token.
127+
*
128+
* The completion token must have the following signature
129+
*
130+
* @code
131+
* void f(boost::system::error_code);
132+
* @endcode
133+
*/
134+
template <class CompletionToken = boost::asio::default_completion_token_t<executor_type>>
135+
auto
136+
async_run(
137+
endpoint ep,
138+
timeouts ts = timeouts{},
139+
CompletionToken token = CompletionToken{})
140+
{
141+
return base_type::async_run(ep, ts, std::move(token));
142+
}
143+
144+
/** @brief Connects and executes a request asynchronously.
145+
*
146+
* Combines the other `async_run` overload with `async_exec` in a
147+
* single function. This function is useful for users that want to
148+
* send a single request to the server and close it.
149+
*
150+
* @param ep Redis endpoint.
151+
* @param req Request object.
152+
* @param adapter Response adapter.
153+
* @param ts Timeouts used by the operation.
154+
* @param token Asio completion token.
155+
*
156+
* The completion token must have the following signature
157+
*
158+
* @code
159+
* void f(boost::system::error_code, std::size_t);
160+
* @endcode
161+
*
162+
* Where the second parameter is the size of the response in bytes.
163+
*/
164+
template <
165+
class Adapter = detail::response_traits<void>::adapter_type,
166+
class CompletionToken = boost::asio::default_completion_token_t<executor_type>>
167+
auto async_run(
168+
endpoint ep,
169+
resp3::request const& req,
170+
Adapter adapter,
171+
timeouts ts,
172+
CompletionToken token = CompletionToken{})
173+
{
174+
return base_type::async_run(ep, req, adapter, ts, std::move(token));
175+
}
176+
93177
private:
94178
using base_type = connection_base<executor_type, connection<AsyncReadWriteStream>>;
95179
using this_type = connection<next_layer_type>;
@@ -106,19 +190,18 @@ class connection :
106190
template <class> friend struct detail::run_op;
107191

108192
template <class CompletionToken>
109-
auto async_connect(CompletionToken&& token)
193+
auto async_connect(timeouts ts, CompletionToken&& token)
110194
{
111195
return boost::asio::async_compose
112196
< CompletionToken
113197
, void(boost::system::error_code)
114-
>(detail::connect_with_timeout_op<this_type>{this}, token, stream_);
198+
>(detail::connect_with_timeout_op<this_type>{this, ts}, token, stream_);
115199
}
116200

117201
void close() { stream_.close(); }
118202
auto is_open() const noexcept { return stream_.is_open(); }
119203
auto& lowest_layer() noexcept { return stream_.lowest_layer(); }
120204

121-
config cfg_;
122205
AsyncReadWriteStream stream_;
123206
};
124207

0 commit comments

Comments
 (0)