I was wondering that if we run multiple calls of async_resolve than in practice the io_context doesn't run more than one request at the time due to a known limitation.
Here's a sample example where I'd expect that each resolve request will yield while it wait for the dns response to return, and move to the next request and so on.
but from looking at Wireshark it looks like the next resolve is performed only after the previous one finishes.
boost::asio::ip::tcp::resolver resolver(io_ctx_);
const auto results1 = resolver.async_resolve(host1_, std::to_string(port1_), yield);
const auto results2 = resolver.async_resolve(host2_, std::to_string(port2_), yield);
const auto results3 = resolver.async_resolve(host3_, std::to_string(port3_), yield);
Does io_context handle only one resolve request at a time ?
You specifically yield and resume the coroutine for each invocation.
Your own co-routine is what is explicitly serializing the invocations.
Here's a direct, self-contained repro:
Live On Coliru
Printing e.g.
Using handler tracking:
Promises
There are many ways to fix it, but let me try the "new"
use_promiseapproach here:Live On Coliru
Same output, but now using handler tracking:
BONUS
Using awaitable operators with c++20 coroutines is usually friendlier, and doesn't require Boost Context (or Boost Coroutine):
Live On Coliru
Or use parallel groups, specifically to make it dynamic with a ranged parallel group:
Live On Coliru
Both these c++20 example result in identical execution: