mirror of
https://github.com/jlu5/PyLink.git
synced 2024-12-25 04:02:45 +01:00
control: move plugin shutdown & pidfile cleanup routines to atexit
It is possible for PyLink to shutdown indirectly by disconnecting all networks. In these cases, the shutdown routines never ran at all...
This commit is contained in:
parent
7e51d3a7f5
commit
998beb51b5
@ -5,6 +5,7 @@ import signal
|
|||||||
import os
|
import os
|
||||||
import threading
|
import threading
|
||||||
import sys
|
import sys
|
||||||
|
import atexit
|
||||||
|
|
||||||
from pylinkirc import world, utils, conf, classes
|
from pylinkirc import world, utils, conf, classes
|
||||||
from pylinkirc.log import log, makeFileLogger, stopFileLoggers, stdoutLogLevel
|
from pylinkirc.log import log, makeFileLogger, stopFileLoggers, stdoutLogLevel
|
||||||
@ -22,15 +23,16 @@ def remove_network(ircobj):
|
|||||||
def _print_remaining_threads():
|
def _print_remaining_threads():
|
||||||
log.debug('_shutdown(): Remaining threads: %s', ['%s/%s' % (t.name, t.ident) for t in threading.enumerate()])
|
log.debug('_shutdown(): Remaining threads: %s', ['%s/%s' % (t.name, t.ident) for t in threading.enumerate()])
|
||||||
|
|
||||||
def _shutdown(irc=None):
|
def _remove_pid():
|
||||||
"""Shuts down the Pylink daemon."""
|
# Remove our pid file.
|
||||||
global tried_shutdown
|
log.info("Removing our pid file.")
|
||||||
if tried_shutdown: # We froze on shutdown last time, so immediately abort.
|
try:
|
||||||
_print_remaining_threads()
|
os.remove("%s.pid" % conf.confname)
|
||||||
raise KeyboardInterrupt("Forcing shutdown.")
|
except OSError:
|
||||||
|
log.exception("Failed to remove PID, ignoring...")
|
||||||
tried_shutdown = True
|
|
||||||
|
|
||||||
|
def _kill_plugins(irc=None):
|
||||||
|
log.info("Shutting down plugins.")
|
||||||
for name, plugin in world.plugins.items():
|
for name, plugin in world.plugins.items():
|
||||||
# Before closing connections, tell all plugins to shutdown cleanly first.
|
# Before closing connections, tell all plugins to shutdown cleanly first.
|
||||||
if hasattr(plugin, 'die'):
|
if hasattr(plugin, 'die'):
|
||||||
@ -40,6 +42,25 @@ def _shutdown(irc=None):
|
|||||||
except: # But don't allow it to crash the server.
|
except: # But don't allow it to crash the server.
|
||||||
log.exception('coremods.control: Error occurred in die() of plugin %s, skipping...', name)
|
log.exception('coremods.control: Error occurred in die() of plugin %s, skipping...', name)
|
||||||
|
|
||||||
|
# We use atexit to register certain functions so that when PyLink cleans up after itself if it
|
||||||
|
# shuts down because all networks have been disconnected.
|
||||||
|
atexit.register(_remove_pid)
|
||||||
|
atexit.register(_kill_plugins)
|
||||||
|
|
||||||
|
def _shutdown(irc=None):
|
||||||
|
"""Shuts down the Pylink daemon."""
|
||||||
|
global tried_shutdown
|
||||||
|
if tried_shutdown: # We froze on shutdown last time, so immediately abort.
|
||||||
|
_print_remaining_threads()
|
||||||
|
raise KeyboardInterrupt("Forcing shutdown.")
|
||||||
|
|
||||||
|
tried_shutdown = True
|
||||||
|
|
||||||
|
# HACK: run the _kill_plugins trigger with the current IRC object. XXX: We should really consider removing this
|
||||||
|
# argument, since no plugins actually use it to do anything.
|
||||||
|
atexit.unregister(_kill_plugins)
|
||||||
|
_kill_plugins(irc)
|
||||||
|
|
||||||
# Remove our main PyLink bot as well.
|
# Remove our main PyLink bot as well.
|
||||||
utils.unregisterService('pylink')
|
utils.unregisterService('pylink')
|
||||||
|
|
||||||
@ -47,13 +68,6 @@ def _shutdown(irc=None):
|
|||||||
# Disconnect all our networks.
|
# Disconnect all our networks.
|
||||||
remove_network(ircobj)
|
remove_network(ircobj)
|
||||||
|
|
||||||
# Remove our pid file.
|
|
||||||
log.info("Removing our pid.")
|
|
||||||
try:
|
|
||||||
os.remove("%s.pid" % conf.confname)
|
|
||||||
except OSError:
|
|
||||||
log.exception("Failed to remove PID, ignoring...")
|
|
||||||
|
|
||||||
log.info("Waiting for remaining threads to stop; this may take a few seconds. If PyLink freezes "
|
log.info("Waiting for remaining threads to stop; this may take a few seconds. If PyLink freezes "
|
||||||
"at this stage, press Ctrl-C to force a shutdown.")
|
"at this stage, press Ctrl-C to force a shutdown.")
|
||||||
_print_remaining_threads()
|
_print_remaining_threads()
|
||||||
|
2
pylink
2
pylink
@ -91,4 +91,4 @@ if __name__ == '__main__':
|
|||||||
log.info("Loaded plugins: %s", ', '.join(sorted(world.plugins.keys())))
|
log.info("Loaded plugins: %s", ', '.join(sorted(world.plugins.keys())))
|
||||||
|
|
||||||
from pylinkirc import coremods
|
from pylinkirc import coremods
|
||||||
coremods.permissions.resetPermissions()
|
coremods.permissions.resetPermissions() # XXX we should probably move this to run on import
|
||||||
|
Loading…
Reference in New Issue
Block a user