Arjunsingh
Arjunsingh

Reputation: 763

How to close the loop if one of the task is completed in asyncio

I have 3 tasks. -

def task_a(): 
    while True:
        file.write()
        asyncio.sleep(10)

def task_b():
    while True:
        file.write()
        asyncio.sleep(10)


def task_c():
    # do something

main.py -

try:
    loop = asyncio.get_event_loop()
    A = loop.create_task(task_a)
    B = loop.create_task(task_b)
    C = loop.create_task(task_c)

    awaitable_pending_tasks = asyncio.all_tasks()
    execution_group = asyncio.gather(*awaitable_pending_tasks, return_exceptions=True)
        fi_execution = loop.run_until_complete(execution_group)
finally:
    loop.run_forever()

I want to make sure that the loop is exited when the task_c is completed. Tried with loop.close() in finally but since it's async, it closes in between.

task_a and task_b write to a file and there is another process running that checks the time the file was modified. If it's greater than a minute it will result in an error(which I don't want) hence I've put the while loop in it and once its written I added a sleep()

Once task_c is complete, I need the loop to stop.

Other answers on StackOverflow looked complicated to understand. Any way we can do this?

Upvotes: 0

Views: 1656

Answers (1)

user4815162342
user4815162342

Reputation: 154846

You could call loop.run_until_complete or asyncio.run (but not run_forever) to run a function that prepares the tasks you need and then only awaits the one you want to terminate the loop (untested):

async def main():
    asyncio.create_task(task_a)
    asyncio.create_task(task_b)
    await task_c
    tasks = set(asyncio.all_tasks()) - set([asyncio.current_task()])
    for t in tasks:
        t.cancel()
    await asyncio.gather(*tasks, return_exceptions=True)

asyncio.run(main())
# or asyncio.get_event_loop().run_until_complete(main())

Upvotes: 2

Related Questions