8000 co_awaiting multiple tasks in parallel · Issue #74 · qcoro/qcoro · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

co_awaiting multiple tasks in parallel #74

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
danvratil 8000 opened this issue May 19, 2022 · 7 comments
Open

co_awaiting multiple tasks in parallel #74

danvratil opened this issue May 19, 2022 · 7 comments
Labels
enhancement New feature or request

Comments

@danvratil
Copy link
Collaborator

I have already ran into a case in QCoro where being able to co_await multiple tasks in parallel would make the code simpler , and I think there's a lot of potential hidden in this feature.

The idea of for the API is:

// co_await two tasks, return result of both as a tuple
template<typename T1, typename T2>
Task<std::tuple<T1, T2>> operator && (Task<T1>, Task<T2>);
// co_await two tasks, return result of the first task to finish, cancel the other
template<typename T1, typename T2>
Task<std::variant<T1, T2>> operator || (Task<T1>, Task<T2>);

There's a question of composability, .e.g. should

co_await task1 && task2 && task3;

return std::tuple<T1, T2, T3> or std::tuple<std::tuple<T1, T2>, T3>?

Same goes for the operator|| - should the result be std::variant<T1, T2, T3> or std::variant<std::variant<T1, T2>, T3>?

I see benefit in having both, so I guess we could have allOf and firstOf functions to provide the flat result (as shown below) and leave the operator|| and operator&& to return the nested types following the natural rules of operator precedence.

template<typename Ts ...> Task<std::tuple<Ts ...>> allOf(Task<Ts> ...);
template<typename Ts ...> Task<std::variant<Ts ...>> firstOf(Task<Ts> ...);
@danvratil danvratil added the enhancement New feature or request label May 19, 2022
@danvratil
Copy link
Collaborator Author

After some initial designing, the std::variant for return type of firstOf will not work, as firstOf<Task<int>, Task<int>>(...) would lead to std::variant<int, int>, which is illegal. The code could fold it into std::variant<int>, but then the information about which task has actually finished is lost.

So I think the only viable solution is for firstOf is to return std::tuple<std::optional<Ts ...>>

@5fuheyan
Copy link
5fuheyan commented Jul 8, 2022

Is this feature available now?

@danvratil
Copy link
Collaborator Author

Not yet, I only have an experimental implementation of allOf (you can check the feature/composition branch).

@DeveloperPaul123
Copy link
Contributor

This would also be extremely useful for us as well, specifically && and || operators for awaitables.

@danvratil
Copy link
Collaborator Author

The && operator for Task<T> is implemented on the feature/composition branch and should work (just needs some unit tests). I just didn't want to merge it without having the || operator as well. Unfortunately, the || operator is more tricky, as it requires QCoro coroutines to become cancellable (so that when one coroutine resolves, the other one is cancelled), which is a whole big topic of its own. I have yet to do some exploration into that area....

@DeveloperPaul123
Copy link
Contributor

Would std::stop_token be a viable option for coroutine cancelation? I too needed the ability to cancel a coroutine in our application and am playing around with this as a way to stop coroutine execution.

@danvratil
Copy link
Collaborator Author

It might be, but there are drawbacks as well - I created #107 with some brainstorming regarding cancellation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

3 participants
0