Move signal handling out of the controller

This commit is contained in:
Neil Booth 2016-11-08 00:04:10 +09:00
parent 680eb83af1
commit 1393f6a030
2 changed files with 30 additions and 20 deletions

View File

@ -9,16 +9,29 @@
'''Script to kick off the server.''' '''Script to kick off the server.'''
import asyncio import asyncio
import logging import logging
import os import os
import signal
import traceback import traceback
from functools import partial
from server.env import Env from server.env import Env
from server.controller import Controller from server.controller import Controller
def cancel_tasks(loop):
# Cancel and collect the remaining tasks
tasks = asyncio.Task.all_tasks()
for task in tasks:
task.cancel()
try:
loop.run_until_complete(asyncio.gather(*tasks))
except asyncio.CancelledError:
pass
def main_loop(): def main_loop():
'''Get tasks; loop until complete.''' '''Get tasks; loop until complete.'''
if os.geteuid() == 0: if os.geteuid() == 0:
@ -33,16 +46,26 @@ def main_loop():
#loop.set_debug(True) #loop.set_debug(True)
controller = Controller(loop, env) controller = Controller(loop, env)
controller.start()
tasks = asyncio.Task.all_tasks(loop) # Signal handlers
def on_signal(signame):
'''Call on receipt of a signal to cleanly shutdown.'''
logging.warning('received {} signal, preparing to shut down'
.format(signame))
loop.stop()
for signame in ('SIGINT', 'SIGTERM'):
loop.add_signal_handler(getattr(signal, signame),
partial(on_signal, signame))
controller.start()
try: try:
loop.run_until_complete(asyncio.gather(*tasks)) loop.run_forever()
except asyncio.CancelledError:
logging.warning('task cancelled; asyncio event loop closing')
finally: finally:
controller.stop() controller.stop()
loop.close() cancel_tasks(loop)
loop.close()
def main(): def main():

View File

@ -12,7 +12,6 @@ client-serving data such as histories.
''' '''
import asyncio import asyncio
import signal
import ssl import ssl
from functools import partial from functools import partial
@ -46,11 +45,6 @@ class Controller(LoggedClass):
for coro in coros: for coro in coros:
asyncio.ensure_future(coro) asyncio.ensure_future(coro)
# Signal handlers
for signame in ('SIGINT', 'SIGTERM'):
self.loop.add_signal_handler(getattr(signal, signame),
partial(self.on_signal, signame))
async def on_update(self, height, touched): async def on_update(self, height, touched):
if not self.servers: if not self.servers:
self.servers = await self.start_servers() self.servers = await self.start_servers()
@ -98,10 +92,3 @@ class Controller(LoggedClass):
'''Close the listening servers.''' '''Close the listening servers.'''
for server in self.servers: for server in self.servers:
server.close() server.close()
def on_signal(self, signame):
'''Call on receipt of a signal to cleanly shutdown.'''
self.logger.warning('received {} signal, preparing to shut down'
.format(signame))
for task in asyncio.Task.all_tasks(self.loop):
task.cancel()