Skip to content

async_exec never returns when the network is disconnected and then restored. #212

Closed
@DuanYu923

Description

@DuanYu923

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

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions