0

I have a asyncio coroutine work_loop that contains a while loop. When the program is interrupted, both while loop should finish their current iteration before exiting in order to have a clean shutdown.

import asyncio

async def work_loop():
    """ How to allow the while loop to finish before exiting this coroutine? """
    while True:
        for i in range(3):
            print(f"[A] Doing step {i+1}")
            await asyncio.sleep(1)
            if i == 2:
                print("Done!")

async def work_loop_b():
    """ How to allow the while loop to finish before exiting this coroutine? """
    while True:
        for i in range(3):
            print(f"[B] Doing step {i+1}")
            await asyncio.sleep(2)
            if i == 2:
                print("Done!")
                
async def main():
    work_loop_task = asyncio.create_task(work_loop())
    work_loop_b_task = asyncio.create_task(work_loop_b())
    await work_loop_task
    
if __name__ == '__main__':
    loop = asyncio.new_event_loop()
    asyncio.set_event_loop(loop)
    main_task = asyncio.ensure_future(main(), loop=loop)
        
    try:
        loop.run_until_complete(main_task)
    finally:
        loop.close()

Right now, if the program is interrupted, it will exit before the while loop is complete, and with the messages:

[A] Doing step 1
[A] Doing step 2
[B] Doing step 1
[A] Doing step 3
[A] Done!
[B] Doing step 2
^CTraceback (most recent call last):


...

KeyboardInterrupt
Task was destroyed but it is pending!
task: <Task pending name='Task-1' coro=<main() running at /home/gameveloster/temp/app.py:13> wait_for=<Task pending name='Task-2' coro=<work_loop() running at /home/gameveloster/temp/app.py:7> wait_for=<Future pending cb=[Task.task_wakeup()]> cb=[Task.task_wakeup()]>>

How can I do a clean shutdown by having the while loop complete its current iteration before quitting?

Nyxynyx
  • 61,411
  • 155
  • 482
  • 830
gameveloster
  • 901
  • 1
  • 6
  • 18

0 Answers0