I'm trying to add a console input listener to an async app, and I've hit an interesting problem.
The following code doesn't terminate when it should, and instead continues waiting for input after the script has terminated:
import asyncio
loop = asyncio.get_event_loop()
async def quit_after(timeout):
await asyncio.sleep(timeout)
print('main function terminating now') # this could simulate a crash, or a proper exit
async def print_input_loop():
while True:
# executor thread is daemon - should terminate when script ends, but doesn't
text = await loop.run_in_executor(None, input, '> ')
print(text)
if __name__ == '__main__':
loop.create_task(print_input_loop())
try:
loop.run_until_complete(quit_after(5))
finally:
loop.close()
print('reached end of file - script should now terminate')
I've looked into other methods for getting input asynchronously, such as using add_reader() on sys.stdin, but this doesn't work on Windows, and I need my solution to be platform independent.
Does anyone know either a better way to get console input asynchronously that will gracefully halt when the app halts, or a way to fix my existing code so that it cleanly exits?
A possible workaround is to disable the exit function for threads in concurrent.futures:
def disable_exit_for_threadpool_executor():
import atexit
import concurrent.futures
atexit.unregister(concurrent.futures.thread._python_exit)
Also, aioconsole provides a cross-platform function for handling console input in asyncio:
import aioconsole
async def echo_loop():
while True:
text = await aioconsole.ainput('> ')
print(text.strip())
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With