8000 Introduce task combinators (`&&`/`||`) · Issue #250 · qcoro/qcoro · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Introduce task combinators (&&/||) #250

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
Tracked by #254
danvratil opened this issue Sep 29, 2024 · 0 comments
Open
Tracked by #254

Introduce task combinators (&&/||) #250

danvratil opened this issue Sep 29, 2024 · 0 comments
Labels
enhancement New feature or request qcoro2

Comments

@danvratil
Copy link
Collaborator
danvratil commented Sep 29, 2024

Often it's useful to be able to co_await multiple awaitables in parallel. Note that there is a pre-existing task (#74) and even a branch (feature/composition), which got stalled due to any/|| not being possible without cancellation support in QCoro::Task<T>

QCoro2::all() / &&

QCoro2::all() takes an arbitrary number of awaitables and returns a single Task<T> that resolves when all the inner awaitables resolve. && is just a syntactic sugar.

The return type would be a tuple with results of all awaitables:

** TODO: What should really be the return type here if Ts are mixed RTasks and Tasks or other awaitables?**

template<typename ... Awaitable Ts>
auto all(Ts ... &&ts) -> Task<std::tuple<awaitable_result_t<Ts> ...>>

Additionally, we should provide overloads for different behaviors:

// Force lazy evaluation of the entire group. If a group member is eager, it's still evaluated eagerly,
// but if there are lazy taks, they do get evaluated lazily
template<typename ... Awaitable Ts>
auto all(Lazy,  Ts... &&ts) -> QCoro::LazyTask<std::tuple<awaitable_result_t<Ts> ...>>

// Force lazy evaluation with possibility for cancellation. Requires all tasks to be RTask or LazyRTask.
// Same behavior as `Lazy`, but can be cancelled at any time.
template<typename ... RTaskLike Ts>
auto all(LazyCancellable,  Ts... &&ts) -> QCoro2::LazyRTask<std::tuple<awaitable_result_t<Ts> ...>>

// Force possibility for cancellation. Requires all tasks to be RTask or LazyRTask.
template<typename ... RTaskLike Ts>
auto all(Cancellable, Ts ...&&ts) -> QCoro2::RTask<std::tuple<awaitable_result_t<Ts> ...>>

operator &&:

TODO: How to treat different combinations of awaitable types?

template<Awaitable T1, Awaitable T2>
auto operator &&(T1 &&t1, T2 &&t2) -> Task<std::tuple<awaitable_result_t<T1>, awaitable_result_t<T2>>>

Usage:

const auto [blog, comments, backlings] = co_await QCoro::all(
    fetchData("https://api.example.com/post/42"),
    fetchData("https://api.example.com/post/42/comments"),
    fetchData("https://api.example.com/post/42/backlinks")
);

QCoro2::any()/||

QCoro2::any is like QCoro2::all(), except it resolves the moment any awaitable finishes, returning its result and cancelling all the other awaitables.

The signature is mostly identical to all(), except for the return type. It should accept any awaitable, but have a special casing for Task<T> where it would cancel it if it does not win the race. If the awaitable is not Task<T>, the documentation must be clear on the fact that it will be left to run to completion, but its result will be discarded.

The return type would once again be std::tuple, but it would be a std::tuple of std::optionals, indicating which awaitable was the winner:

TODO: Lazy evaluation
TODO: Properly define the semantics for non-cancellable types - maybe don't allow them at all? What's the point of using any if you can't cancel the other tasks anyway...

template<typename ... Awaitable Ts>
auto any(Ts ... &&ts) -> Task<std::tuple<std::optional<awaitable_result_t<Ts> ...>>>
@danvratil danvratil added enhancement New feature or request qcoro2 labels Sep 29, 2024
@danvratil danvratil changed the title Add support for co_awaiting multiple async tasks Introduce task combinators (&&/||) Oct 6, 2024
@danvratil danvratil changed the title Introduce task combinators (&&/||) Introduce task combinators (&&/||) Oct 6, 2024
@danvratil danvratil mentioned this issue Oct 6, 2024
3 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request qcoro2
Projects
Status: Todo
Development

No branches or pull requests

1 participant
0