-
Notifications
You must be signed in to change notification settings - Fork 36
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
async_exec never returns when the network is disconnected and then restored. #212
Comments
try this Password: changeme |
I can't reproduce this problem. Using the iptables commands you suggested above I get
Can you enable logging and send me the result? |
@mzimbres use co_await conn_->async_exec(req, resp, asio::deferred)
|
Apologies for the incorrect information I provided earlier. The key point lies in the timing of closing the port. It appears that once the log "connected to endpoint Connect timeout." is printed and the port is then restored, it will not reconnect. I tried changing the connect_timeout to 300 seconds, and then found that there is still a difference between using "asio::experimental::as_tuple(asio::deferred)" and "asio::deferred": use asio::experimental::as_tuple(asio::deferred)
use asio::deferred
|
If I understand you correctly your code sample works correctly with asio::co_spawn(ioc, Test(), [](std::exception_ptr p) {
if (p) {
// Please log this as well
std::rethrow_exception(p);
}
}); |
@mzimbres Thank you very much, as you mentioned, the async_exec function threw an exception. Another question, why does it stop attempting to reconnect after the first timeout, is there any special consideration for this? I tried to read the code, and it seems that "reconnection_op" will keep reconnecting unless cancel(operation::reconnection) or cancel(operation::all) is called, but the reconnection timeout does not seem to trigger them. perhaps I missed something. |
Do you mean it stops trying to reconnect after the exception is thrown or in general? Can you provide me with an example with instructions that reproduces the problem? So far I could not reproduce it. |
@mzimbres Please follow these steps for operation: |
Did you really mean #include <boost/redis/connection.hpp>
#include <boost/asio/deferred.hpp>
#include <boost/asio/experimental/as_tuple.hpp>
#include <boost/asio/co_spawn.hpp>
#include <boost/asio/detached.hpp>
#include <boost/asio/consign.hpp>
#include <iostream>
#if defined(BOOST_ASIO_HAS_CO_AWAIT)
namespace asio = boost::asio;
using boost::redis::request;
using boost::redis::response;
using boost::redis::config;
using boost::redis::connection;
constexpr auto use_nothrow_awaitable = asio::experimental::as_tuple(asio::use_awaitable);
// Called from the main function (see main.cpp)
auto co_main(config cfg) -> asio::awaitable<void>
{
auto conn = std::make_shared<connection>(co_await asio::this_coro::executor);
conn->async_run(cfg, {boost::redis::logger::level::debug}, asio::consign(asio::detached, conn));
for (int i = 0; ; ++i) {
request req;
req.push("PING", "Hello");
response<std::string> resp;
co_await conn->async_exec(req, resp, use_nothrow_awaitable);
std::cout << "===> " << i << std::endl;
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;
}
#endif // defined(BOOST_ASIO_HAS_CO_AWAIT)
|
The Redis service is deployed in the alibaba cloud, so I've hidden the host, username, and password in my code. |
I used the code you provided and the main.cpp from the example. The only difference is that I added the username and password. The result is the same after execution. I am using Redis service version 7.0.18, but I think the reconnection issue should not be related to the version of Redis.
|
In order to eliminate interference from the cloud vendor's Redis version and network, I compiled and installed Redis 7.2.3 on my own computer, set it to start without a password, and launched the redis-server. I used the main.cpp from the example and the code you provided above without making any changes. redis.config
log
|
Please reopen if the problem is not solved. Thanks. |
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:
version:boost1.86
The method to simulate the disconnection and restoration of the network is through firewall commands:
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.The text was updated successfully, but these errors were encountered: