Closed
Description
In scenarios where the connection is broken and then restored, the redis::connection does not always return to a normal state. I have not delved into the internal implementation, which may be related to the coroutine scheduling mechanism of asio. The following simple example code can reproduce the issue:
constexpr auto use_nothrow_awaitable =
asio::experimental::as_tuple(asio::deferred);
awaitable<void> Test() {
redis::config cfg;
cfg.addr.host = "";
cfg.addr.port = "6379";
cfg.username = "";
cfg.password = "";
cfg.use_ssl = false;
conn_ = std::make_shared<redis::connection>(io_context.get_executor());
conn_->async_run(cfg, {}, asio::consign(asio::detached, conn_));
for (;;) {
redis::request req;
req.push("PING", "Hello");
redis::response<std::string> resp;
// normal
co_await conn_->async_exec(req, resp, use_nothrow_awaitable);
// probability never return
//co_await conn_->async_exec(req, resp, asio::use_awaitable);
// probability never return
//co_await conn_->async_exec(req, resp, asio::deferred);
LOG_INFO("resp [%s]", std::get<0>(resp).value().c_str());
asio::steady_timer timer(co_await asio::this_coro::executor);
timer.expires_after(std::chrono::seconds(1));
co_await timer.async_wait(use_nothrow_awaitable);
}
co_return;
}
version:boost1.86
The method to simulate the disconnection and restoration of the network is through firewall commands:
iptables -A OUTPUT -p tcp --dport=6379 -j DROP
iptables -D OUTPUT -p tcp --dport=6379 -j DROP
Additionally, as mentioned here, cppusing cancel_if_not_connected = true
with asio::deferred is also fine, but I believe this may not be a good solution.
Metadata
Metadata
Assignees
Labels
No labels