wsgi: do not respawn on missing eventlet hub

Eventlet 'poll' hub is not available on OSX, wsgi.Server workers have no
chance to start but the error was not caught and they were respawned
endlessly. This patch makes these workers not to be respawned.

This has the nice side-effect of avoiding the test suite to get stuck in
test_multiprocessing on OSX, filling syslog.

Change-Id: I565d21f5c6861102e96d6953ace29cde57e8ec38
This commit is contained in:
Patrick Mezard 2012-05-06 14:49:48 +02:00
parent 28d85923fa
commit 2c102130ed
3 changed files with 27 additions and 4 deletions

View File

@ -38,6 +38,12 @@ gettext.install('glance', unicode=1)
from glance.common import config
from glance.common import wsgi
from glance.common import exception
def fail(returncode, e):
sys.stderr.write("ERROR: %s\n" % e)
sys.exit(returncode)
if __name__ == '__main__':
@ -50,6 +56,7 @@ if __name__ == '__main__':
server = wsgi.Server()
server.start(app, conf, default_port=9292)
server.wait()
except exception.WorkerCreationFailure, e:
fail(2, e)
except RuntimeError, e:
sys.stderr.write("ERROR: %s\n" % e)
sys.exit(1)
fail(1, e)

View File

@ -232,3 +232,7 @@ class RegionAmbiguity(GlanceException):
message = _("Multiple 'image' service matches for region %(region)s. This "
"generally means that a region is required and you have not "
"supplied one.")
class WorkerCreationFailure(GlanceException):
message = _("Server worker creation failed: %(reason)s.")

View File

@ -192,7 +192,15 @@ class Server(object):
if os.WIFEXITED(status) or os.WIFSIGNALED(status):
self.logger.error(_('Removing dead child %s') % pid)
self.children.remove(pid)
self.run_child()
if os.WIFEXITED(status) and os.WEXITSTATUS(status) == 2:
self.logger.error(_('Not respawning child %d, cannot '
'recover from termination') % pid)
if not self.children:
self.logger.error(
_('All workers have terminated. Exiting'))
self.running = False
else:
self.run_child()
except OSError, err:
if err.errno not in (errno.EINTR, errno.ECHILD):
raise
@ -232,7 +240,11 @@ class Server(object):
def run_server(self):
"""Run a WSGI server."""
eventlet.wsgi.HttpProtocol.default_request_version = "HTTP/1.0"
eventlet.hubs.use_hub('poll')
try:
eventlet.hubs.use_hub('poll')
except Exception:
msg = _("eventlet 'poll' hub is not available on this platform")
raise exception.WorkerCreationFailure(reason=msg)
eventlet.patcher.monkey_patch(all=False, socket=True)
self.pool = eventlet.GreenPool(size=self.threads)
try: