def start(self, application, default_port): """ Run a WSGI server with the given application. :param application: The application to be run in the WSGI server :param default_port: Port to bind to if none is specified in conf """ pgid = os.getpid() try: # NOTE(flaper87): Make sure this process # runs in its own process group. os.setpgid(pgid, pgid) except OSError: # NOTE(flaper87): When running cdsoss-control, # (cdsoss's functional tests, for example) # setpgid fails with EPERM as cdsoss-control # creates a fresh session, of which the newly # launched service becomes the leader (session # leaders may not change process groups) # # Running cdsoss-(api|registry) is safe and # shouldn't raise any error here. pgid = 0 def kill_children(*args): """Kills the entire process group.""" signal.signal(signal.SIGTERM, signal.SIG_IGN) signal.signal(signal.SIGINT, signal.SIG_IGN) self.running = False os.killpg(pgid, signal.SIGTERM) def hup(*args): """ Shuts down the server, but allows running requests to complete """ signal.signal(signal.SIGHUP, signal.SIG_IGN) self.running = False self.application = application self.sock = get_socket(default_port) os.umask(0o27) # ensure files are created with the correct privileges self.logger = logging.getLogger('cdsoss.wsgi.server') if CONF.workers == 0: # Useful for profiling, test, debug etc. self.pool = self.create_pool() self.pool.spawn_n(self._single_run, self.application, self.sock) return else: self.logger.info(_("Starting %d workers") % CONF.workers) signal.signal(signal.SIGTERM, kill_children) signal.signal(signal.SIGINT, kill_children) signal.signal(signal.SIGHUP, hup) while len(self.children) < CONF.workers: self.run_child()
# vim: tabstop=4 shiftwidth=4 softtabstop=4 # -*- coding: utf-8 -*- import sys from eventlet import event from eventlet import greenthread from cdsoss.common.gettextutils import _ from cdsoss.common import log as logging from cdsoss.common import timeutils LOG = logging.getLogger(__name__) class LoopingCallDone(Exception): """Exception to break out and stop a LoopingCall. The poll-function passed to LoopingCall can raise this exception to break out of the loop normally. This is somewhat analogous to StopIteration. An optional return-value can be included as the argument to the exception; this return-value will be returned by LoopingCall.wait() """ def __init__(self, retvalue=True): """:param retvalue: Value that LoopingCall.wait() should return.""" self.retvalue = retvalue