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?