`gather` and `select` to replace `Combine` and `First`
See original GitHub issueCombine
and First
only work on triggers and tasks, not on coroutines or any other kind of awaitable. This is kind of limiting. You can work around it by wrapping coroutine arguments in fork
and wrapping awaitables in coroutine functions and fork
🤢. They also have crappy semantics. Combine
returns nothing. First
returns only the result of the first await
to complete. There is no way of knowing which input fired. First
also does not handle cancelling tasks that are passed in, which is very annoying when you are simply using tasks to work-around the fact that First
doesn’t take coroutines or awaitables.
I propose two new interfaces to replace Combine
and First
respectively: gather
and select
. gather
will run any given awaitables concurrently and return a list of the results of each await
statement. select
will run any given awaitables concurrently, and return once the first of the awaitables finishes. It will return the index (by position of the arguments) of the awaitable that fired, and the result of the await
statement. Like Combine
and First
, exceptions will be propagated by default, and the awaitables that did not throw an exception will be cancelled safely.
async def gather(*args: Awaitable[Any]) -> List[Any]:
...
async def select(*args: Awaitable[Any]) -> Tuple[int, Any]:
...
gather
is extremely similar to asyncio.gather
. There is no interface in asyncio
for something like gather
, but only for the first awaitable to finish. I decided on the word select
because it is similar to the select
statement in Go, albeit not just for queues.
Once these interface are implemented and tested, perhaps Combine
and First
should be deprecated. This is simply so that there is “one way to do it”.
A follow-on may add an interface for catching exceptions as results rather than propagating them, much like asyncio.gather
supports.
Issue Analytics
- State:
- Created 2 years ago
- Comments:13 (11 by maintainers)
Top GitHub Comments
cocotb has accumulated a lot of deprecations over the past few versions. We try not to break things on minor versions, so 2.0 should get rid of those, plus some other breaking changes that are sorely needed.
There are issues with
asyncio.wait
. As soon as you segregate the futures into two different lists you obliterate any information matching the inputs to the outputs. Such a function should return a single list so that users can map outputs back to inputs.