asyncio - How can coroutines be used in signal handlers?

coroutine, python, python-asyncio, signals

Solution

Syntax for python >=3.5

loop = asyncio.get_event_loop()
for signame in ('SIGINT', 'SIGTERM'):
    loop.add_signal_handler(getattr(signal, signame),
                            lambda: asyncio.ensure_future(ask_exit(signame)))

Problem

I am developing an application that uses asyncio from python3.4 for networking. When this application shuts down cleanly, a node needs to "disconnect" from the hub. This disconnect is an active process that requires a network connection so the loop needs to wait for this to complete before shutting down. My issue is that using a coroutine as a signal handler will result in the application not shutting down. Please consider the following example: ``` import asyncio import functools import os import signal @asyncio.coroutine def ask_exit(signame): print("got signal %s: exit" % signame) yield from asyncio.sleep(10.0) loop.stop() loop = asyncio.get_event_loop() for signame in ('SIGINT', 'SIGTERM'): loop.add_signal_handler(getattr(signal, signame), functools.partial(ask_exit, signame)) print("Event loop running forever, press CTRL+c to interrupt.") print("pid %s: send SIGINT or SIGTERM to exit." % os.getpid()) loop.run_forever() ``` If you run this example and then press Ctrl+C, nothing will happen. The question is, how do I make this behavior happen with siganls and coroutines?

Original source