0

I am trying to run a simple asyncio loop that I want to run continuously until Control + C is pressed, which should stop the main function and run a function to shutdown the loop. I am using the following code:

import asyncio

async def run():
    while True:
        print("Running")

async def shutdown():
    print("Starting to shutdown")
    await asyncio.sleep(1)
    print("Finished sleeping")

try:
    loop = asyncio.get_event_loop()
    loop.create_task(run())
    loop.run_forever()
except KeyboardInterrupt:
    loop.stop()
    loop.run_until_complete(asyncio.gather(*[shutdown()]))

When running this code and pressing Control + C the script doesn't shutdown gracefully as I expected (also based on this stackoverflow answer but I get the following error:

Traceback (most recent call last):
  File "test.py", line 25, in <module>
    loop.run_until_complete(asyncio.gather(*[shutdown()]))
  File "/usr/lib/python3.7/asyncio/base_events.py", line 585, in run_until_complete
    raise RuntimeError('Event loop stopped before Future completed.')
RuntimeError: Event loop stopped before Future completed.
ERROR:asyncio:Task exception was never retrieved
future: <Task finished coro=<run() done, defined at test.py:8> exception=KeyboardInterrupt()>
Traceback (most recent call last):
  File "test.py", line 22, in <module>
    loop.run_forever()
  File "/usr/lib/python3.7/asyncio/base_events.py", line 541, in run_forever
    self._run_once()
  File "/usr/lib/python3.7/asyncio/base_events.py", line 1786, in _run_once
    handle._run()
  File "/usr/lib/python3.7/asyncio/events.py", line 88, in _run
    self._context.run(self._callback, *self._args)
  File "test.py", line 10, in run
    print("Running")
KeyboardInterrupt

Can anyone tell me where I am going wrong and how I should change my code to solve the issue?

Oxbowerce
  • 430
  • 5
  • 14
  • Add a print statement to ensure you are in the `KeyboardInterrupt` exception handler prior to the error message. If so, that would indicate you need to do some sort of wait on your loop prior to the `stop` call. (Just guessing, I haven't got asyncio chops yet...) – RufusVS Jul 10 '21 at 20:38
  • Adding a print statment in the `except` block shows that it indeed in entered, also because after that the first print statement in the `shutdown` function shows up. It seems whenever the `await asyncio.sleep(1)` is run the program exits with the error. – Oxbowerce Jul 11 '21 at 09:48
  • Do you think [asyncio debug mode](https://docs.python.org/3.6/library/asyncio-dev.html#debug-mode-of-asyncio) might help? – RufusVS Jul 11 '21 at 15:25
  • I wasn't aware that this mode was available, however it doesn't really help me solve the issue since the only extra error message I get is `ERROR - Task exception was never retrieved`. – Oxbowerce Jul 31 '21 at 12:51

0 Answers0