What is the relationship between Boost::Asio and C++20 coroutines?
Asked Answered
D

1

7

I started trying to learn Boost::Asio by reading the documentation and example code. I found things difficult to understand, particularly because the model seemed similar to coroutines.

I then decided to learn about coroutines, starting with this cppcon talk. In the linked talk, the following line was given in an example of coroutine usage. The example was written in 2014, so the syntax may not match C++20 coroutines.

auto conn = await Tcp::connect.Read("127.0.0.1", 1337)

This feels similar to the stated goals of Boost::Asio. However, in the examples section of the Boost::Asio documentation, there is an example that mixes Boost::Asio and C++20 coroutines. (I do not yet understand this example.)

What is the relationship between Boost::Asio and coroutines? Do coroutines replace parts of Boost::Asio? If I am not doing networking, should I still use Boost::Asio? Where do std::async and the senders/receivers proposal fit into all this?

Dislimn answered 12/7, 2022 at 20:46 Comment(0)
Z
7

Q. What is the relationship between Boost::Asio and coroutines?

C++20 coroutines are one of the completion token mechanisms provided with any Asio compliant async API

Q. Do coroutines replace parts of Boost::Asio?

Not 1 on 1.

In practice people may feel a lot less need to write asio::spawn (stackful) coroutines, because in practice the stackfulness is rarely required and makes the implementation (very) heavy in comparison. Also, up to Boost 1.81(?) asio::spawn will still depend on Boost Coroutine (work is underway to remove that and implement the functionality directly on top of Boost Context).

Another where C++20 coroutines seem to remove friction is when providing a dual API (sync and async). I've heard people suggest that it is possible to implement the synchronous version in terms of the asynchronous version transparently. I'm not up to speed with the specifics of this pattern (and whether it is ready for production code yet).

Q. If I am not doing networking, should I still use Boost::Asio?

Should? No. But you may. In general, with c++20 coroutines you will want to use some library like cppcoro or indeed Asio. That's because no user-level library facilities have been standardized yet.

In Asio the interesting bits are:

  1. experimental stuff like channels (channel and concurrent_channel), parallel_group, wait_for_{all,one,any}

  2. the general purpose facility coro which has a lot of flexibility. You could see it as the most useful 80% of cppcoro but

    • all in one relatively simple class template:

      1. coro<T> -> simple generator
      2. coro<T(U)> -> generator with input
      3. coro<void, T> task producing a T
    • integrated with Asio executors

This documentation is a pretty decent introduction¹, especially when you're familiar with concepts from other libraries/languages.

Q. Where do std::async and the senders/receivers proposal fit into all this?

I'm not sure. I seem to remember Chris Kohlhoff wrote that proposal. The concept may be lurking under the channel/deferred abstractions in Asio already.


¹ Hat tip @klemensmorgenstern

Zumstein answered 12/7, 2022 at 21:31 Comment(4)
Deleted my previous comment. Answered my follow-up with a google search.Dislimn
Boost Asio introduced the uniform completion token.This was also proposed for standardization. "Asio compliant" is an informal term I used to losely mean "APIs conforming to the uniform completion token model"Zumstein
You say "That's because no user-level library facilities have been standardized yet." I'm not sure what you mean. Do you mean "no user-level library facilities for networking" or "no user-level library facilities for asynchronous i/o" or something else? promise not to delete this comment this time.Dislimn
I meant user-level (library) facilities for C++ coroutines. (and lol :)) Only the language feature has been baked and it's intentionally very general and hence Very Hard To Use (TM)Zumstein

© 2022 - 2024 — McMap. All rights reserved.