niedz., 13 sie 2023 o 11:55 Klemens Morgenstern < klemensdavidmorgenstern@gmail.com> napisał(a):
On Sun, Aug 13, 2023 at 5:33 PM Andrzej Krzemienski via Boost
wrote: Hi Everyone, I would like to thank Klemens for writing and sharing this library. I am sure the community needs a higher level library for asynchronous computations based on C++20 coroutines. Boost.Async addresses the need. I would like to ask a couple of questions to better understand the design goals and the scope of the library.
Thanks for looking into the library.
Q1. Is single-threaded-ness the design goal? Or is the plan to enable multi-threaded use cases? There is a GitHub issue ( https://github.com/klemens-morgenstern/async/issues/19) suggesting the latter.
I think most of the use cases for asynchronous code are best served being single threaded. That is you have a single IO thread and offload intense work (e.g. complex calculations) onto a thread pool.
You can have multiple threads using async, but they can't interact safely with each other. I am considering adding support for that, but that's already possible by using asio's concurrenct_channel. So it's not high on the priority list.
I understand the priorities, and they seem fine with me. Still, I would like to get a picture of the scope of this library. The docs say "simple single threaded asynchronicity", which seems to be implying "no multithreading by design". Your above response is more like "ultimately both single-threaded and multithreaded, but only single-threaded for now". Either option is fine, but it would be easier for potential users if one of these was indicated clearly.
Q2. Reading through the docs, I get an impression that Boost.Async is "Either a wrapper over ASIO, or an isolated usage for a generator". They seem like two unrelated worlds. The former requires a hard prerequisite
having a Boost.ASIO library (with Boost version at least 1.82). The latter can hardly be called "asynchronous". Generators, the way I understand
of them,
are perfectly synchronous. Is this impression correct?
It is not. Generators are also async, i.e. they run on an event loop and can to asynchronous co_awaits.
I also don't think "wrapper" is the correct term; async is like any coroutine library in that it needs an event loop (some of which are built into the language). So it uses asio's which I considered the best choice.
Two follow-up questions for me to understand better. One. Is this library prepared to work with any other event loop than Boost.Asio (or standalone ASIO)? If so, is there an example somewhere? Two. Does the `generator` example from the docs also involve the ASIO's executor?
The following are more remarks regarding the choice of names.
Q3. The docs say that `promise` and `task` differ primarily by their
level
of eagerness. But the names do not seem to reflect this. What is the rationale or the intuition behind those names?
Promises are eager in JS, tasks lazy in Python.
The above explanation should be included as notes in the docs of the corresponding types.
Can also be remembered like this: If you make a promise you should see it through eagerly, while a task can wait until it's scheduled.
The explanation for a `task` works for me. But I do not understand the analogy with the promise.
R1. I find the name `use_op` uninformative. The examples in documentation suggest that it is an *adapter*: they change the Boost.ASIO interface
into
the Boost.Async interface. Is that correct?
Technically into an expression that can be used with co_await from any coroutine.
All of asio's completion tokens are *adapter*s in a sense, e.g. use_future adopts it into a std::future. The type returned is an implementation of `op`, so `use_op` matches the asio pattern here.
I agree that all ASIO's completion tokens can be thought of as *adapters*. What I am missing is a clear indication that: `use_op` is a *completion tokens* in the ASIO model Even with a link to the ASIO docs for the completion token. Ok, now I also get that `op` is an Awaitable that wraps ASIO operation Is this statement precise and correct? (Does ASIO use the term "operation"?) Still the name `op` is very short and not informative. Does it need to be that short? Is it expected to be used very often? And this one: async::use_op.as_default_on() Is it not too clever? op_adapter() would be shorter, have a dedicated signature that could be separately documented. Regards, &rzej;
Regards, &rzej;
_______________________________________________ Unsubscribe & other changes: