Skip to content
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

212 async exec never returns when the network is disconnected and then restored #217

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion example/sync_connection.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@

/* Copyright (c) 2018-2023 Marcelo Zimbres Silva ([email protected])
/* Copyright (c) 2018-2024 Marcelo Zimbres Silva ([email protected])
*
* Distributed under the Boost Software License, Version 1.0. (See
* accompanying file LICENSE.txt)
Expand Down
2 changes: 1 addition & 1 deletion include/boost/redis.hpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* Copyright (c) 2018-2023 Marcelo Zimbres Silva ([email protected])
/* Copyright (c) 2018-2024 Marcelo Zimbres Silva ([email protected])
*
* Distributed under the Boost Software License, Version 1.0. (See
* accompanying file LICENSE.txt)
Expand Down
2 changes: 1 addition & 1 deletion include/boost/redis/adapter/adapt.hpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* Copyright (c) 2018-2023 Marcelo Zimbres Silva ([email protected])
/* Copyright (c) 2018-2024 Marcelo Zimbres Silva ([email protected])
*
* Distributed under the Boost Software License, Version 1.0. (See
* accompanying file LICENSE.txt)
Expand Down
2 changes: 1 addition & 1 deletion include/boost/redis/adapter/detail/adapters.hpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* Copyright (c) 2018-2023 Marcelo Zimbres Silva ([email protected])
/* Copyright (c) 2018-2024 Marcelo Zimbres Silva ([email protected])
*
* Distributed under the Boost Software License, Version 1.0. (See
* accompanying file LICENSE.txt)
Expand Down
2 changes: 1 addition & 1 deletion include/boost/redis/adapter/detail/response_traits.hpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* Copyright (c) 2018-2023 Marcelo Zimbres Silva ([email protected])
/* Copyright (c) 2018-2024 Marcelo Zimbres Silva ([email protected])
*
* Distributed under the Boost Software License, Version 1.0. (See
* accompanying file LICENSE.txt)
Expand Down
2 changes: 1 addition & 1 deletion include/boost/redis/adapter/detail/result_traits.hpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* Copyright (c) 2018-2023 Marcelo Zimbres Silva ([email protected])
/* Copyright (c) 2018-2024 Marcelo Zimbres Silva ([email protected])
*
* Distributed under the Boost Software License, Version 1.0. (See
* accompanying file LICENSE.txt)
Expand Down
2 changes: 1 addition & 1 deletion include/boost/redis/adapter/ignore.hpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* Copyright (c) 2018-2023 Marcelo Zimbres Silva ([email protected])
/* Copyright (c) 2018-2024 Marcelo Zimbres Silva ([email protected])
*
* Distributed under the Boost Software License, Version 1.0. (See
* accompanying file LICENSE.txt)
Expand Down
2 changes: 1 addition & 1 deletion include/boost/redis/adapter/result.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@

/* Copyright (c) 2018-2023 Marcelo Zimbres Silva ([email protected])
/* Copyright (c) 2018-2024 Marcelo Zimbres Silva ([email protected])
*
* Distributed under the Boost Software License, Version 1.0. (See
* accompanying file LICENSE.txt)
Expand Down
2 changes: 1 addition & 1 deletion include/boost/redis/config.hpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* Copyright (c) 2018-2023 Marcelo Zimbres Silva ([email protected])
/* Copyright (c) 2018-2024 Marcelo Zimbres Silva ([email protected])
*
* Distributed under the Boost Software License, Version 1.0. (See
* accompanying file LICENSE.txt)
Expand Down
2 changes: 1 addition & 1 deletion include/boost/redis/connection.hpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* Copyright (c) 2018-2023 Marcelo Zimbres Silva ([email protected])
/* Copyright (c) 2018-2024 Marcelo Zimbres Silva ([email protected])
*
* Distributed under the Boost Software License, Version 1.0. (See
* accompanying file LICENSE.txt)
Expand Down
4 changes: 2 additions & 2 deletions include/boost/redis/detail/connection_base.hpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* Copyright (c) 2018-2023 Marcelo Zimbres Silva ([email protected])
/* Copyright (c) 2018-2024 Marcelo Zimbres Silva ([email protected])
*
* Distributed under the Boost Software License, Version 1.0. (See
* accompanying file LICENSE.txt)
Expand Down Expand Up @@ -705,7 +705,7 @@ class connection_base {
template <class, class> friend struct writer_op;
template <class, class> friend struct run_op;
template <class> friend struct exec_op;
template <class, class, class> friend struct run_all_op;
template <class, class, class> friend struct runner_op;

void cancel_push_requests()
{
Expand Down
77 changes: 13 additions & 64 deletions include/boost/redis/detail/connector.hpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* Copyright (c) 2018-2023 Marcelo Zimbres Silva ([email protected])
/* Copyright (c) 2018-2024 Marcelo Zimbres Silva ([email protected])
*
* Distributed under the Boost Software License, Version 1.0. (See
* accompanying file LICENSE.txt)
Expand All @@ -12,9 +12,8 @@
#include <boost/asio/compose.hpp>
#include <boost/asio/connect.hpp>
#include <boost/asio/coroutine.hpp>
#include <boost/asio/experimental/parallel_group.hpp>
#include <boost/asio/ip/tcp.hpp>
#include <boost/asio/steady_timer.hpp>
#include <boost/asio/cancel_after.hpp>
#include <string>
#include <chrono>

Expand All @@ -30,65 +29,29 @@ struct connect_op {

template <class Self>
void operator()( Self& self
, std::array<std::size_t, 2> const& order = {}
, system::error_code const& ec1 = {}
, asio::ip::tcp::endpoint const& ep= {}
, system::error_code const& ec2 = {})
, system::error_code const& ec = {}
, asio::ip::tcp::endpoint const& ep= {})
{
BOOST_ASIO_CORO_REENTER (coro)
{
ctor_->timer_.expires_after(ctor_->timeout_);

BOOST_ASIO_CORO_YIELD
asio::experimental::make_parallel_group(
[this](auto token)
{
auto f = [](system::error_code const&, auto const&) { return true; };
return asio::async_connect(*stream, *res_, f, token);
},
[this](auto token) { return ctor_->timer_.async_wait(token);}
).async_wait(
asio::experimental::wait_for_one(),
std::move(self));

if (is_cancelled(self)) {
self.complete(asio::error::operation_aborted);
return;
}
asio::async_connect(*stream, *res_,
[](system::error_code const&, auto const&) { return true; },
asio::cancel_after(ctor_->timeout_, std::move(self)));

switch (order[0]) {
case 0: {
ctor_->endpoint_ = ep;
self.complete(ec1);
} break;
case 1:
{
if (ec2) {
self.complete(ec2);
} else {
self.complete(error::connect_timeout);
}
} break;
ctor_->endpoint_ = ep;

default: BOOST_ASSERT(false);
if (ec == asio::error::operation_aborted) {
ec == error::connect_timeout;
}

self.complete(ec);
}
}
};

template <class Executor>
class connector {
public:
using timer_type =
asio::basic_waitable_timer<
std::chrono::steady_clock,
asio::wait_traits<std::chrono::steady_clock>,
Executor>;

connector(Executor ex)
: timer_{ex}
{}

void set_config(config const& cfg)
{ timeout_ = cfg.connect_timeout; }

Expand All @@ -102,28 +65,14 @@ class connector {
return asio::async_compose
< CompletionToken
, void(system::error_code)
>(connect_op<connector, Stream>{this, &stream, &res}, token, timer_);
}

std::size_t cancel(operation op)
{
switch (op) {
case operation::connect:
case operation::all:
timer_.cancel();
break;
default: /* ignore */;
}

return 0;
>(connect_op<connector, Stream>{this, &stream, &res}, token);
}

auto const& endpoint() const noexcept { return endpoint_;}

private:
template <class, class> friend struct connect_op;

timer_type timer_;
std::chrono::steady_clock::duration timeout_ = std::chrono::seconds{2};
asio::ip::tcp::endpoint endpoint_;
};
Expand Down
2 changes: 1 addition & 1 deletion include/boost/redis/detail/handshaker.hpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* Copyright (c) 2018-2023 Marcelo Zimbres Silva ([email protected])
/* Copyright (c) 2018-2024 Marcelo Zimbres Silva ([email protected])
*
* Distributed under the Boost Software License, Version 1.0. (See
* accompanying file LICENSE.txt)
Expand Down
2 changes: 1 addition & 1 deletion include/boost/redis/detail/health_checker.hpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* Copyright (c) 2018-2023 Marcelo Zimbres Silva ([email protected])
/* Copyright (c) 2018-2024 Marcelo Zimbres Silva ([email protected])
*
* Distributed under the Boost Software License, Version 1.0. (See
* accompanying file LICENSE.txt)
Expand Down
2 changes: 1 addition & 1 deletion include/boost/redis/detail/helper.hpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* Copyright (c) 2018-2023 Marcelo Zimbres Silva ([email protected])
/* Copyright (c) 2018-2024 Marcelo Zimbres Silva ([email protected])
*
* Distributed under the Boost Software License, Version 1.0. (See
* accompanying file LICENSE.txt)
Expand Down
66 changes: 14 additions & 52 deletions include/boost/redis/detail/resolver.hpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* Copyright (c) 2018-2023 Marcelo Zimbres Silva ([email protected])
/* Copyright (c) 2018-2024 Marcelo Zimbres Silva ([email protected])
*
* Distributed under the Boost Software License, Version 1.0. (See
* accompanying file LICENSE.txt)
Expand All @@ -12,9 +12,8 @@
#include <boost/redis/error.hpp>
#include <boost/asio/compose.hpp>
#include <boost/asio/coroutine.hpp>
#include <boost/asio/experimental/parallel_group.hpp>
#include <boost/asio/ip/tcp.hpp>
#include <boost/asio/steady_timer.hpp>
#include <boost/asio/cancel_after.hpp>
#include <string>
#include <chrono>

Expand All @@ -28,66 +27,31 @@ struct resolve_op {

template <class Self>
void operator()( Self& self
, std::array<std::size_t, 2> order = {}
, system::error_code ec1 = {}
, asio::ip::tcp::resolver::results_type res = {}
, system::error_code ec2 = {})
, system::error_code ec = {}
, asio::ip::tcp::resolver::results_type res = {})
{
BOOST_ASIO_CORO_REENTER (coro)
{
resv_->timer_.expires_after(resv_->timeout_);

BOOST_ASIO_CORO_YIELD
asio::experimental::make_parallel_group(
[this](auto token)
{
return resv_->resv_.async_resolve(resv_->addr_.host, resv_->addr_.port, token);
},
[this](auto token) { return resv_->timer_.async_wait(token);}
).async_wait(
asio::experimental::wait_for_one(),
std::move(self));

if (is_cancelled(self)) {
self.complete(asio::error::operation_aborted);
return;
}
resv_->resv_.async_resolve(
resv_->addr_.host,
resv_->addr_.port,
asio::cancel_after(resv_->timeout_, std::move(self)));

switch (order[0]) {
case 0: {
// Resolver completed first.
resv_->results_ = res;
self.complete(ec1);
} break;

case 1: {
if (ec2) {
// Timer completed first with error, perhaps a
// cancellation going on.
self.complete(ec2);
} else {
// Timer completed first without an error, this is a
// resolve timeout.
self.complete(error::resolve_timeout);
}
} break;

default: BOOST_ASSERT(false);
resv_->results_ = res;

if (ec == asio::error::operation_aborted) {
ec == error::resolve_timeout;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be ec = error::resolve_timeout?

}
self.complete(ec);
}
}
};

template <class Executor>
class resolver {
public:
using timer_type =
asio::basic_waitable_timer<
std::chrono::steady_clock,
asio::wait_traits<std::chrono::steady_clock>,
Executor>;

resolver(Executor ex) : resv_{ex} , timer_{ex} {}
resolver(Executor ex) : resv_{ex} {}

template <class CompletionToken>
auto async_resolve(CompletionToken&& token)
Expand All @@ -104,7 +68,6 @@ class resolver {
case operation::resolve:
case operation::all:
resv_.cancel();
timer_.cancel();
break;
default: /* ignore */;
}
Expand All @@ -126,7 +89,6 @@ class resolver {
template <class> friend struct resolve_op;

resolver_type resv_;
timer_type timer_;
address addr_;
std::chrono::steady_clock::duration timeout_;
asio::ip::tcp::resolver::results_type results_;
Expand Down
Loading