summaryrefslogtreecommitdiff
path: root/Mailman/bin/qrunner.py
diff options
context:
space:
mode:
authorBarry Warsaw2008-02-25 00:24:03 -0500
committerBarry Warsaw2008-02-25 00:24:03 -0500
commit6965bd89216a8d759ff8ea35ca4d1e88b0c35906 (patch)
tree642089474463c2632ab358a8f6d982af19ed24ca /Mailman/bin/qrunner.py
parentaab29f252ebefb1520714080a90bb42a25393f18 (diff)
downloadmailman-6965bd89216a8d759ff8ea35ca4d1e88b0c35906.tar.gz
mailman-6965bd89216a8d759ff8ea35ca4d1e88b0c35906.tar.zst
mailman-6965bd89216a8d759ff8ea35ca4d1e88b0c35906.zip
Rework the basic infrastructure for qrunner process control. Split out the
functionality of mailmanctl into a separate master watcher script. mailmanctl has not yet been updated but that'll happen next. Fix DELIVERY_MODULE to name a handler instead of a module. Change make_instance to use pkg_resources instead of module.__file__. Change the qrunner and master processes coordination so that the qrunners are not restarted on SIGINT, because otherwise C-c just doesn't work. Now SIGUSR1 is how we'll implement 'mailman restart'. Add a database commit so that initializing the schema doesn't lock the sqlite database. Also, don't try to initialize the schema if the tables already exist. Use some sqlite magic to do this test. Move mailman.cfg.in into a new package Mailman/extras inside the tree. Also, MAILMAN_UID and MAILMAN_GID should be integers not strings. Convert the command runner to use an IHandler instance instead of handler module. Similarly for the outgoing runner, DELIVERY_MODULE now names an IHandler instance instead of a handler module.
Diffstat (limited to 'Mailman/bin/qrunner.py')
-rw-r--r--Mailman/bin/qrunner.py28
1 files changed, 20 insertions, 8 deletions
diff --git a/Mailman/bin/qrunner.py b/Mailman/bin/qrunner.py
index 91ecb2ca3..b73643c9d 100644
--- a/Mailman/bin/qrunner.py
+++ b/Mailman/bin/qrunner.py
@@ -95,7 +95,7 @@ each listed by the -l option."""))
parser.add_option('-o', '--once',
default=False, action='store_true', help=_("""\
Run each named qrunner exactly once through its main loop. Otherwise, each
-qrunner runs indefinitely, until the process receives a SIGTERM or SIGINT."""))
+qrunner runs indefinitely, until the process receives signal."""))
parser.add_option('-l', '--list',
default=False, action='store_true',
help=_('List the available qrunner names and exit.'))
@@ -134,13 +134,13 @@ def make_qrunner(name, slice, range, once=False):
__import__(modulename)
except ImportError, e:
if opts.subproc:
- # Exit with SIGTERM exit code so mailmanctl won't try to restart us
+ # Exit with SIGTERM exit code so the master watcher won't try to
+ # restart us.
print >> sys.stderr, _('Cannot import runner module: $modulename')
print >> sys.stderr, e
sys.exit(signal.SIGTERM)
else:
- print >> sys.stderr, e
- sys.exit(1)
+ raise
qrclass = getattr(sys.modules[modulename], classname)
if once:
# Subclass to hack in the setting of the stop flag in _doperiodic()
@@ -155,22 +155,34 @@ def make_qrunner(name, slice, range, once=False):
def set_signals(loop):
- # Set up the SIGTERM handler for stopping the loop
+ """Set up the signal handlers.
+
+ Signals caught are: SIGTERM, SIGINT, SIGUSR1 and SIGHUP. The latter is
+ used to re-open the log files. SIGTERM and SIGINT are treated exactly the
+ same -- they cause qrunner to exit with no restart from the master.
+ SIGUSR1 also causes qrunner to exit, but the master watcher will restart
+ it in that case.
+
+ :param loop: A loop queue runner instance.
+ """
def sigterm_handler(signum, frame):
# Exit the qrunner cleanly
loop.stop()
loop.status = signal.SIGTERM
log.info('%s qrunner caught SIGTERM. Stopping.', loop.name())
signal.signal(signal.SIGTERM, sigterm_handler)
- # Set up the SIGINT handler for stopping the loop. For us, SIGINT is
- # the same as SIGTERM, but our parent treats the exit statuses
- # differently (it restarts a SIGINT but not a SIGTERM).
def sigint_handler(signum, frame):
# Exit the qrunner cleanly
loop.stop()
loop.status = signal.SIGINT
log.info('%s qrunner caught SIGINT. Stopping.', loop.name())
signal.signal(signal.SIGINT, sigint_handler)
+ def sigusr1_handler(signum, frame):
+ # Exit the qrunner cleanly
+ loop.stop()
+ loop.status = signal.SIGUSR1
+ log.info('%s qrunner caught SIGUSR1. Stopping.', loop.name())
+ signal.signal(signal.SIGUSR1, sigusr1_handler)
# SIGHUP just tells us to rotate our log files.
def sighup_handler(signum, frame):
loginit.reopen()