Skip to content

Commit

Permalink
Simplifies resolve timeout operation.
Browse files Browse the repository at this point in the history
  • Loading branch information
mzimbres committed Oct 21, 2024
1 parent c309c57 commit 53cabf0
Showing 1 changed file with 13 additions and 53 deletions.
66 changes: 13 additions & 53 deletions include/boost/redis/detail/resolver.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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,29 @@ 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;
}

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_->resv_.async_resolve(
resv_->addr_.host,
resv_->addr_.port,
asio::cancel_after(resv_->timeout_, std::move(self)));

resv_->results_ = res;

// TODO: map operation_canceled into 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 +66,6 @@ class resolver {
case operation::resolve:
case operation::all:
resv_.cancel();
timer_.cancel();
break;
default: /* ignore */;
}
Expand All @@ -126,7 +87,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

0 comments on commit 53cabf0

Please sign in to comment.