diff options
author | Brant Knudson <bknudson@us.ibm.com> | 2015-04-22 11:33:00 -0500 |
---|---|---|
committer | Brant Knudson <bknudson@us.ibm.com> | 2015-04-22 11:36:19 -0500 |
commit | 65a50eebb8d0a53a2c4c226eb9a564c4d535ac68 (patch) | |
tree | d776b664e945a70b37ecf4c7cc7782a1e0cba476 | |
parent | 128dbdedd527de22d5e61a21d214b02a5af7b27c (diff) | |
download | keystone-65a50eebb8d0a53a2c4c226eb9a564c4d535ac68.tar.gz |
Sync oslo-incubator Ie51669bd278288b768311ddf56ad31a2f28cc7ab
This syncs to oslo-incubator to commit 64b5819 and also includes
51280db.
Change-Id: I7b43a67a0b67fe0ff5ac3d87708ecc4ab52102f8
Depends-On: Ie51669bd278288b768311ddf56ad31a2f28cc7ab
Closes-Bug: #1446583
(cherry picked from commit 797da5f05444e7cfbf55df52867ade6107834f00)
-rw-r--r-- | keystone/openstack/common/service.py | 39 |
1 files changed, 29 insertions, 10 deletions
diff --git a/keystone/openstack/common/service.py b/keystone/openstack/common/service.py index cfae56b74..d209b8e8e 100644 --- a/keystone/openstack/common/service.py +++ b/keystone/openstack/common/service.py @@ -199,18 +199,30 @@ class ServiceWrapper(object): class ProcessLauncher(object): - def __init__(self): - """Constructor.""" + _signal_handlers_set = set() + + @classmethod + def _handle_class_signals(cls, *args, **kwargs): + for handler in cls._signal_handlers_set: + handler(*args, **kwargs) + def __init__(self, wait_interval=0.01): + """Constructor. + + :param wait_interval: The interval to sleep for between checks + of child process exit. + """ self.children = {} self.sigcaught = None self.running = True + self.wait_interval = wait_interval rfd, self.writepipe = os.pipe() self.readpipe = eventlet.greenio.GreenPipe(rfd, 'r') self.handle_signal() def handle_signal(self): - _set_signals_handler(self._handle_signal) + self._signal_handlers_set.add(self._handle_signal) + _set_signals_handler(self._handle_class_signals) def _handle_signal(self, signo, frame): self.sigcaught = signo @@ -230,15 +242,12 @@ class ProcessLauncher(object): def _child_process_handle_signal(self): # Setup child signal handlers differently - def _sigterm(*args): - signal.signal(signal.SIGTERM, signal.SIG_DFL) - raise SignalExit(signal.SIGTERM) - def _sighup(*args): signal.signal(signal.SIGHUP, signal.SIG_DFL) raise SignalExit(signal.SIGHUP) - signal.signal(signal.SIGTERM, _sigterm) + # Parent signals with SIGTERM when it wants us to go away. + signal.signal(signal.SIGTERM, signal.SIG_DFL) if _sighup_supported(): signal.signal(signal.SIGHUP, _sighup) # Block SIGINT and let the parent send us a SIGTERM @@ -329,8 +338,8 @@ class ProcessLauncher(object): def _wait_child(self): try: - # Block while any of child processes have exited - pid, status = os.waitpid(0, 0) + # Don't block if no child processes have exited + pid, status = os.waitpid(0, os.WNOHANG) if not pid: return None except OSError as exc: @@ -359,6 +368,10 @@ class ProcessLauncher(object): while self.running: wrap = self._wait_child() if not wrap: + # Yield to other threads if no children have exited + # Sleep for a short time to avoid excessive CPU usage + # (see bug #1095346) + eventlet.greenthread.sleep(self.wait_interval) continue while self.running and len(wrap.children) < wrap.workers: self._start_child(wrap) @@ -383,8 +396,14 @@ class ProcessLauncher(object): if not _is_sighup_and_daemon(self.sigcaught): break + cfg.CONF.reload_config_files() + for service in set( + [wrap.service for wrap in self.children.values()]): + service.reset() + for pid in self.children: os.kill(pid, signal.SIGHUP) + self.running = True self.sigcaught = None except eventlet.greenlet.GreenletExit: |