Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does asio::ip::tcp::resolver::async_resolve need to be external canceled?

I use the function async_resolve()

using tcp = boost::asio::ip::tcp;

namespace asio = boost::asio;


template <class Request, class Response>
class HttpsClient : public std::enable_shared_from_this<HttpsClient<Request, Response>>
{
  mutable asio::io_context::strand  m_strand;
  tcp::resolver                     m_resolver;
  const std::string                 m_host;
  const std::string                 m_service;

  void doSend(Request request, Handler handler)
  {
    ...

    m_resolver.async_resolve(
      m_host, m_service,
      asio::bind_executor(
        m_strand, std::bind(&HttpsClient::onResolve, this->shared_from_this(), _1, _2)
      )
    );

    ... 
  }
  
  void onResolve(const boost::system::error_code& ec, tcp::resolver::results_type results);

Should I cancel async_resolve() for example after some timeout? My question is - does async_resolve() give any guaranties to return in smart time limitations.

like image 476
sba Avatar asked Feb 24 '26 22:02

sba


1 Answers

I'd have more high-level timeout that will cancel any DNS request as well as other IO operations when they fail to complete in timely fashion.

After all, it's only marginally interesting to know the difference, and a DNS resolution is usually a step in a sequential IO chain that represents something like "lookup, connect, handshake, receive, reply".

Of course, make sure to log the actual cause of the timeout. This can be as simple as:

 void on_timeout(error_code ec) {
     if (ec != asio::errors::operations_aborted)) {
          _resolver.cancel();
          _socket.cancel();
          // any other parts of the highlevel IO operation that might need cancelling
     }
 }

The operations_aborted is what indicates cancellation. So, we checked it to avoid cancelling other operations when the timer itself is cancelled (e.g. what happens naturally during the destructor or when setting a new expiration).

Now you can detect operations_aborted in your completion handler(s) for individual steps and use that to log appropriately ("on_resolve: operation aborted") so you have the information. If you wish you can add a more verbose message whenever the on_timeout was hit so you can see the difference between other logic flows that result in aborted operations.

My question is - does async_resolve() give any guaranties to return in smart time limitations

I'm not actually sure about that. And the above is why.

It seems very reasonable to assume that all DNS clients inevitably have a timeout, because the protocol is UDP, which means inherently susceptible to packet loss. It would simply be irresponsible to not expect and handle packet loss (in fact, there will no doubt be a "retry N times" approach for the same reasons).

I do notice some other applications that tend to get stuck for some fixed amount of time when DNS is not responding, but I'm not sure what makes it timeout. I suppose it might be platform dependent.

like image 182
sehe Avatar answered Feb 26 '26 18:02

sehe



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!