Boost logo

Boost :

From: Andrzej Krzemienski (akrzemi1_at_[hidden])
Date: 2023-08-14 17:12:00


niedz., 13 sie 2023 o 11:55 Klemens Morgenstern <
klemensdavidmorgenstern_at_[hidden]> napisał(a):

> On Sun, Aug 13, 2023 at 5:33 PM Andrzej Krzemienski via Boost
> <boost_at_[hidden]> 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
> of
> > having a Boost.ASIO library (with Boost version at least 1.82). The
> latter
> > can hardly be called "asynchronous". Generators, the way I understand
> 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:
> http://lists.boost.org/mailman/listinfo.cgi/boost
>


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk