Feature request - WaitAny accepts task
sandyscott opened this issue · 3 comments
Hi,
I've found a few situations in my current project where I'd quite like to use a task as one of the inputs to WaitAny
.
e.g:
async def background_coro():
# Insert work here...
await asyncio.sleep(5)
async def main()
switch = ESwitch(#some pin)
background_task = asyncio.create_task(background_coro())
await WaitAny((switch.close, background_task).wait()
background_task.cancel()
I can easily solve this with passing around Event
objects, but it muddies the picture compared to how simple waiting for the task alone would be (ie. await background_coro()
)
I appreciate there may be lots of good reasons why this can't work, I just thought I'd share a little frustration in case there's something I've missed.
[EDIT]
I think this ELO
class will do what you want. It takes an arbitrary coroutine or a running task and converts it to an ELO.
class ELO:
def __init__(self, coro, *args, **kwargs):
self.coro = coro
self.args = args
self.kwargs = kwargs
async def wait(self):
if isinstance(self.coro, asyncio.Task):
return await self.coro
# Coroutine
return await self.coro(*self.args, **self.kwargs)
async def background_coro(t): # Demo of arg passing
# Insert work here...
await asyncio.sleep(t)
async def main()
switch = ESwitch(#some pin)
await WaitAny((switch.close, ELO(background_task, 5))
background_task.cancel()
I will incorporate into events.py
but I need to ensure that WaitAll
handles return values (the wait
methods of existing ELO
instances don't return a value). I'll report back when this is done and documented.
Thank you for pointing me to a useful enhancement.
Thank you! That's a really tidy solution.
I have now pushed an update. The ELO
class has some changes but remains very compact.
The changes were necessary because, unlike an Event
, a Task
can return a value. It can also be cancelled. There are no changes to WaitAll
or WaitAny
, and cancellation is handled in such a way that WaitAll
and WaitAny
behave as if the Task
had terminated normally. The application can determine how the Task
terminated.
It is documented and there is a test script.
I'll close the issue as complete, but comments are of course welcome.