diff options
Diffstat (limited to 'mailman/bin/master.py')
| -rw-r--r-- | mailman/bin/master.py | 62 |
1 files changed, 42 insertions, 20 deletions
diff --git a/mailman/bin/master.py b/mailman/bin/master.py index 1c45e04f8..d3676629d 100644 --- a/mailman/bin/master.py +++ b/mailman/bin/master.py @@ -1,4 +1,4 @@ -# Copyright (C) 2001-2008 by the Free Software Foundation, Inc. +# Copyright (C) 2001-2009 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # @@ -32,12 +32,13 @@ import socket import logging from datetime import timedelta +from lazr.config import as_boolean from locknix import lockfile from munepy import Enum from mailman import Defaults -from mailman import loginit -from mailman.configuration import config +from mailman.config import config +from mailman.core.logging import reopen from mailman.i18n import _ from mailman.options import Options @@ -237,7 +238,7 @@ class Loop: signal.alarm(int(Defaults.days(1))) # SIGHUP tells the qrunners to close and reopen their log files. def sighup_handler(signum, frame): - loginit.reopen() + reopen() for pid in self._kids: os.kill(pid, signal.SIGHUP) log.info('Master watcher caught SIGHUP. Re-opening log files.') @@ -269,7 +270,9 @@ class Loop: :param spec: A queue runner spec, in a format acceptable to bin/qrunner's --runner argument, e.g. name:slice:count + :type spec: string :return: The process id of the child queue runner. + :rtype: int """ pid = os.fork() if pid: @@ -292,26 +295,43 @@ class Loop: # We should never get here. raise RuntimeError('os.execl() failed') - def start_qrunners(self, qrunners=None): + def start_qrunners(self, qrunner_names=None): """Start all the configured qrunners. :param qrunners: If given, a sequence of queue runner names to start. If not given, this sequence is taken from the configuration file. + :type qrunners: a sequence of strings """ - if not qrunners: - spec_parts = config.qrunners.items() - else: - spec_parts = [] - for qrname in qrunners: - if '.' in qrname: - spec_parts.append((qrname, 1)) - else: - spec_parts.append((config.qrunner_shortcuts[qrname], 1)) - for qrname, count in spec_parts: + if not qrunner_names: + qrunner_names = [] + for qrunner_config in config.qrunner_configs: + # Strip off the 'qrunner.' prefix. + assert qrunner_config.name.startswith('qrunner.'), ( + 'Unexpected qrunner configuration section name: %s', + qrunner_config.name) + qrunner_names.append(qrunner_config.name[8:]) + # For each qrunner we want to start, find their config section, which + # will tell us the name of the class to instantiate, along with the + # number of hash space slices to manage. + for name in qrunner_names: + section_name = 'qrunner.' + name + # Let AttributeError propagate. + qrunner_config = getattr(config, section_name) + if not as_boolean(qrunner_config.start): + continue + package, class_name = qrunner_config['class'].rsplit(DOT, 1) + __import__(package) + # Let AttributeError propagate. + class_ = getattr(sys.modules[package], class_name) + # Find out how many qrunners to instantiate. This must be a power + # of 2. + count = int(qrunner_config.instances) + assert (count & (count - 1)) == 0, ( + 'Queue runner "%s", not a power of 2: %s', name, count) for slice_number in range(count): # qrunner name, slice #, # of slices, restart count - info = (qrname, slice_number, count, 0) - spec = '%s:%d:%d' % (qrname, slice_number, count) + info = (name, slice_number, count, 0) + spec = '%s:%d:%d' % (name, slice_number, count) pid = self._start_runner(spec) log = logging.getLogger('mailman.qrunner') log.debug('[%d] %s', pid, spec) @@ -349,12 +369,14 @@ class Loop: # command line switch was not given. This lets us better handle # runaway restarts (e.g. if the subprocess had a syntax error!) qrname, slice_number, count, restarts = self._kids.pop(pid) + config_name = 'qrunner.' + qrname restart = False if why == signal.SIGUSR1 and self._restartable: restart = True # Have we hit the maximum number of restarts? restarts += 1 - if restarts > config.MAX_RESTARTS: + max_restarts = int(getattr(config, config_name).max_restarts) + if restarts > max_restarts: restart = False # Are we permanently non-restartable? log.debug("""\ @@ -363,10 +385,10 @@ Master detected subprocess exit pid, why, qrname, slice_number + 1, count, ('[restarting]' if restart else '')) # See if we've reached the maximum number of allowable restarts - if restarts > config.MAX_RESTARTS: + if restarts > max_restarts: log.info("""\ qrunner %s reached maximum restart limit of %d, not restarting.""", - qrname, config.MAX_RESTARTS) + qrname, max_restarts) # Now perhaps restart the process unless it exited with a # SIGTERM or we aren't restarting. if restart: |
