From 58519011b8fa23b06c36632fa154bead56588a25 Mon Sep 17 00:00:00 2001 From: James Lu Date: Sun, 27 Mar 2016 21:45:38 -0700 Subject: [PATCH] coreplugin: modularize shutdown routines, handle SIGTERM->shutdown Ref: #179 --- coreplugin.py | 40 ++++++++++++++++++++++++++-------------- 1 file changed, 26 insertions(+), 14 deletions(-) diff --git a/coreplugin.py b/coreplugin.py index 628bfbe..9e83436 100644 --- a/coreplugin.py +++ b/coreplugin.py @@ -4,11 +4,36 @@ coreplugin.py - Implements core PyLink functions as a plugin. import gc import sys +import signal import utils from log import log import world +def _shutdown(irc=None): + """Shuts down the Pylink daemon.""" + for name, plugin in world.plugins.items(): + # Before closing connections, tell all plugins to shutdown cleanly first. + if hasattr(plugin, 'die'): + log.debug('coreplugin: Running die() on plugin %s due to shutdown.', name) + try: + plugin.die(irc) + except: # But don't allow it to crash the server. + log.exception('coreplugin: Error occurred in die() of plugin %s, skipping...', name) + + for ircobj in world.networkobjects.values(): + # Disconnect all our networks. Disable auto-connect first by setting + # the time to negative. + ircobj.serverdata['autoconnect'] = -1 + ircobj.disconnect() + +def sigterm_handler(_signo, _stack_frame): + """Handles SIGTERM gracefully by shutting down the PyLink daemon.""" + log.info("Shutting down on SIGTERM.") + _shutdown() + +signal.signal(signal.SIGTERM, sigterm_handler) + def handle_kill(irc, source, command, args): """Handle KILLs to the main PyLink client, respawning it as needed.""" if args['target'] == irc.pseudoclient.uid: @@ -199,20 +224,7 @@ def shutdown(irc, source, args): log.info('(%s) SHUTDOWN requested by "%s!%s@%s", exiting...', irc.name, u.nick, u.ident, u.host) - for name, plugin in world.plugins.items(): - # Before closing connections, tell all plugins to shutdown cleanly first. - if hasattr(plugin, 'die'): - log.debug('coreplugin: Running die() on plugin %s due to shutdown.', name) - try: - plugin.die(irc) - except: # But don't allow it to crash the server. - log.exception('coreplugin: Error occurred in die() of plugin %s, skipping...', name) - - for ircobj in world.networkobjects.values(): - # Disconnect all our networks. Disable auto-connect first by setting - # the time to negative. - ircobj.serverdata['autoconnect'] = -1 - ircobj.disconnect() + _shutdown(irc) def load(irc, source, args): """.