Boost logo

Boost :

From: Klemens Morgenstern (klemensdavidmorgenstern_at_[hidden])
Date: 2023-07-26 02:43:28


On Wed, Jul 26, 2023 at 2:32 AM Christian Mazakas via Boost
<boost_at_[hidden]> wrote:
>
> > Not if we want users. Coroutines ate much more relevant at this time.
>
> The problem is, this definitely isn't true.
>
> Users already have Asio's `use_awaitable`. A coroutine library that uses
> Asio as its event loop is basically a lateral move from, well, just using Asio
> with `co_spawn` and `use_awaitable`.
>

Asio's awaitable are not anywhere near a complete coroutine library.
They are (by design) meant to work within asio to compose async
operations in a specific way.
You can't "escape" awaitables, i.e. you can't co_await anything else
than an asio::awaitable.

This was one of the reasons I wrote experimental::coro (that can
co_yield) and now you got two,
and since chris addred co_compose three different coroutine types that
can't efficiently interact with each other.

>
> This kind of functionality should never touch the standard because it
> ties a coroutine
> to an execution context. In fact, I'd argue this library's biggest
> mistake is doing exactly that.

It's a mistake shared by all asynchronous coroutine libraries. It's unavoidable.
It would be possible for async to provide it's own type erased type
for the scheduler.
But that would effectively be reimplementing asio::any_io_executor in
immature form,
for the great gain that we don't need to include one header from
another boost library.
I did really consider that, but since any_io_executor allows me to do
that already, I fail to see the point.

>
> What I'm thinking of is something like cppcoro's task type, a task
> type that can only be co_await'd
> by a parent coroutine. To this end, `cppcoro::task<T>` can appear in
> interfaces and then runtime
> authors are free to invoke this via their own runtime-specific
> coroutine types. cppcoro's task stores
> the type-erased coroutine_handle when it's transformed into an
> awaitable so it works with all
> parent coroutine types.

That is what async does.

>
> I think we need vocabulary types like that, with schedulers set
> alongside them. It worries me to see
> an executor directly tied to a coroutine when it's really not
> required, let alone purported that this
> should actually be a standardized practice. There's definitely room
> for innovation in the coroutine
> space but it's hard to argue for a "coroutine library" that I can't
> even use without bringing in Asio.

It is required as soon as you write asynchronous code that does
multiple things at once.
async brings in the executor part of async, so it doesn't need to
create it's own, like cppcoro does for example.

In that case I reproduced well-tested & seasoned code from asio with
my own greenfield impl to avoid an include
of a header that's already present (because boost) for an immature
implementation that's almost the same
while losing the easy usability with boost.beast, boost.process,
boost.mysql & boost.redis.

I know you want to use io_uring and you seem to think you can't.
What's the issue with creating your own awaitables that use io_uring
and co_await them from async's coroutines?


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