2

Ok so basically I need clarification RE: how to use the asyncio.run_until_complete(Future) function.

After adding 3 tasks to my loop I attempt to create a Future"done callback" using the asyncio.wait() function.

In the following code, my event_loop.close() never gets run:

import asyncio async def repeat_message(message, interval_seconds, max_iters=10): iters = 0 while True: print(message) if iters >= max_iters: return 'Complete.' iters += 1 await asyncio.sleep(interval_seconds) if __name__ == "__main__": message_A = "xXxXxXxXxXxXxXxXxXxXx" interval_A = 0.5 message_B = "I LOVE" interval_B = 1 message_C = "EXPLOSIONS!" interval_C = 1.5 event_loop = asyncio.get_event_loop() task_A = event_loop.create_task(repeat_message(message_A, interval_A)) task_B = event_loop.create_task(repeat_message(message_B, interval_B)) task_C = event_loop.create_task(repeat_message(message_C, interval_C)) completed = event_loop.create_future() completed.add_done_callback(asyncio.wait([task_A, task_B, task_C], loop=event_loop)) try: event_loop.run_until_complete(completed) finally: event_loop.close() # Never prints. print('DONE') 

1 Answer 1

4

This is what gather is for. Get rid of your completed future, and use gather this way:

event_loop.run_until_complete(asyncio.gather(task_A, task_B, task_C)) 

What you've written here creates a Future and configures it so that when the future completes, then it will wait for the tasks. But you never complete the future (with set_result() for instance). Future isn't really about running things asynchronously. It's just a data structure that represents "some future value that will be provided by someone eventually calling set_result() or raising an exception with set_exception()." That turns out to often be useful for asynchronous work, but it isn't itself a coroutine.

Sign up to request clarification or add additional context in comments.

2 Comments

Ok awesome! That worked (& makes sense!) Thank you! This actually sheds a lot of light on some questions I had about why Futures & Tasks need to be distinct entities. Correct the recapitulation if I'm wrong but: Whereas a Task must necessarily be non-blocking, instances of its superclass Future don't need to be & this makes them useful as control structures. <--yah?
What if you have a list of tasks, instead of individual variables? I tried this and it throws an error "unhasable type: 'list' "

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.