def run_child(self): def child_hup(*args): """Shuts down child processes, existing requests are handled.""" signal.signal(signal.SIGHUP, signal.SIG_IGN) eventlet.wsgi.is_accepting = False self.sock.close() pid = os.fork() if pid == 0: signal.signal(signal.SIGHUP, child_hup) signal.signal(signal.SIGTERM, signal.SIG_DFL) # ignore the interrupt signal to avoid a race whereby # a child worker receives the signal before the parent # and is respawned unnecessarily as a result signal.signal(signal.SIGINT, signal.SIG_IGN) # The child has no need to stash the unwrapped # socket, and the reference prevents a clean # exit on sighup self._sock = None self.run_server() LOG.info(_LI('Child %d exiting normally'), os.getpid()) # self.pool.waitall() is now called in wsgi's server so # it's safe to exit here sys.exit(0) else: LOG.info(_LI('Started child %s'), pid) self.children.add(pid)
def _remove_children(self, pid): if pid in self.children: self.children.remove(pid) LOG.info(_LI('Removed dead child %s'), pid) elif pid in self.stale_children: self.stale_children.remove(pid) LOG.info(_LI('Removed stale child %s'), pid) else: LOG.warn(_LW('Unrecognised child %s'), pid)
def start(self): verstr = '0.0.2' LOG.info(_LI('Starting %(topic)s node (version %(version)s'), {'topic': self.topic, 'version': verstr}) ctxt = context.get_admin_context() # self.manager.pre_start_hook() LOG.debug("Creating RPC server for service %s", self.topic) target = messaging.Target(topic=self.topic, server=self.host) endpoints = [ self.manager ] self.rpcserver = rpc.get_rpc_server(target, endpoints) self.rpcserver.start() # self.manager.post_start_hook() # periodic_enable set false for the moment. # I just focus on rpc process. if self.periodic_enable: if self.periodic_fuzzy_delay: initial_delay = random.randint(0, self.periodic_fuzzy_delay) else: initial_delay = None self.tg.add_dynamic_timer(self.periodic_tasks, initial_delay=initial_delay, periodic_interval_max= self.periodic_interval_max)
def _single_run(self, application, sock): """Start a WSGI server in a new green thread.""" LOG.info(_LI("Starting single process server")) eventlet.wsgi.server(sock, application, custom_pool=self.pool, url_length_limit=URL_LENGTH_LIMIT, log=self._wsgi_logger, debug=cfg.CONF.debug)
def _verify_and_respawn_children(self, pid, status): if len(self.stale_children) == 0: LOG.debug('No stale children') if os.WIFEXITED(status) and os.WEXITSTATUS(status) != 0: LOG.error(_LE('Not respawning child %d, cannot ' 'recover from termination'), pid) if not self.children and not self.stale_children: LOG.info(_LI('All workers have terminated. Exiting')) self.running = False else: if len(self.children) < self.conf.workers: self.run_child()
def start_wsgi(self): if self.conf.workers == 0: # Useful for profiling, test, debug etc. self.pool = eventlet.GreenPool(size=self.threads) self.pool.spawn_n(self._single_run, self.application, self.sock) return LOG.info(_LI("Starting %d workers") % self.conf.workers) signal.signal(signal.SIGTERM, self.kill_children) signal.signal(signal.SIGINT, self.kill_children) signal.signal(signal.SIGHUP, self.hup) while len(self.children) < self.conf.workers: self.run_child()
def wait_on_children(self): """Wait on children exit.""" while self.running: try: pid, status = os.wait() if os.WIFEXITED(status) or os.WIFSIGNALED(status): self._remove_children(pid) self._verify_and_respawn_children(pid, status) except OSError as err: if err.errno not in (errno.EINTR, errno.ECHILD): raise except KeyboardInterrupt: LOG.info(_LI('Caught keyboard interrupt. Exiting.')) os.killpg(0, signal.SIGTERM) break except exception.SIGHUPInterrupt: self.reload() continue eventlet.greenio.shutdown_safe(self.sock) self.sock.close() LOG.debug('Exited')
from miper.common import rpc _lazy.enable_lazy() LOG = logging.getLogger('miper.api') if __name__ == '__main__': try: logging.register_options(cfg.CONF) cfg.CONF(project='miper', prog='miper-api', version='0.0.2') logging.setup(cfg.CONF, 'miper-api') # messaging configuration rpc.set_defaults(control_exchange='miper') rpc.init(cfg.CONF) conf_file = os.path.join(possible_topdir, "etc", "api-paste.ini") app = deploy.loadapp("config:%s" % conf_file, 'main') host = cfg.CONF.miper_api.bind_host port = cfg.CONF.miper_api.bind_port LOG.info(_LI('Starting Miper API on %(host)s:%(port)s'), {'host': host, 'port': port}) server = wsgi.Server('miper-api', cfg.CONF.miper_api) server.start(app, default_port=port) systemd.notify_once() server.wait() except RuntimeError as ex: sys.exit("ERROR: %s" % six.text_type(ex))
from oslo_log import log as logging from miper.common.i18n import _LI from miper.common import service from miper.common import config _lazy.enable_lazy() LOG = logging.getLogger('miper.engine') rpc_decider_topic_opt = cfg.StrOpt("engine_topic", default="engine", help="The topic scheduler nodes listen on") CONF = cfg.CONF CONF.register_opt(rpc_decider_topic_opt) if __name__ == '__main__': config.parse_args(sys.argv) logging.setup(CONF, "miper-engine") LOG.info(_LI('Starting miper engine service')) server = service.Service.create(binary='miper-engine', topic=CONF.engine_topic) service.serve(server, worker=5) service.wait()