Merge "Eventlet monkey patching should be as early as possible"

This commit is contained in:
Zuul 2019-03-22 22:31:12 +00:00 committed by Gerrit Code Review
commit fef4696e00
9 changed files with 110 additions and 43 deletions

View File

@ -160,6 +160,14 @@ openstack_projects = [
] ]
# -- Custom extensions -------------------------------------------------------- # -- Custom extensions --------------------------------------------------------
# NOTE(mdbooth): (2019-03-20) Sphinx loads policies defined in setup.cfg, which
# includes the placement policy at nova/api/openstack/placement/policies.py.
# Loading this imports nova/api/openstack/__init__.py, which imports
# nova.monkey_patch, which will do eventlet monkey patching to the sphinx
# process. As well as being unnecessary and a bad idea, this breaks on
# python3.6 (but not python3.7), so don't do that.
os.environ['OS_NOVA_DISABLE_EVENTLET_PATCHING'] = '1'
def monkey_patch_blockdiag(): def monkey_patch_blockdiag():
"""Monkey patch the blockdiag library. """Monkey patch the blockdiag library.

View File

@ -22,14 +22,3 @@
:platform: Unix :platform: Unix
:synopsis: Infrastructure-as-a-Service Cloud platform. :synopsis: Infrastructure-as-a-Service Cloud platform.
""" """
import os
os.environ['EVENTLET_NO_GREENDNS'] = 'yes'
# NOTE(rpodolyaka): import oslo_service first, so that it makes eventlet hub
# use a monotonic clock to avoid issues with drifts of system time (see
# LP 1510234 for details)
import oslo_service # noqa
import eventlet # noqa

View File

@ -17,6 +17,7 @@
""" """
WSGI middleware for OpenStack API controllers. WSGI middleware for OpenStack API controllers.
""" """
import nova.monkey_patch # noqa
from oslo_log import log as logging from oslo_log import log as logging
import routes import routes

View File

@ -23,13 +23,11 @@ from nova import context
from nova import exception from nova import exception
from nova import objects from nova import objects
from nova import service from nova import service
from nova import utils
CONF = cfg.CONF CONF = cfg.CONF
CONFIG_FILES = ['api-paste.ini', 'nova.conf'] CONFIG_FILES = ['api-paste.ini', 'nova.conf']
utils.monkey_patch()
objects.register_all() objects.register_all()

View File

@ -1,4 +1,4 @@
# Copyright (c) 2013 Hewlett-Packard Development Company, L.P. # Copyright (c) 2019 Red Hat, Inc.
# All Rights Reserved. # All Rights Reserved.
# #
# Licensed under the Apache License, Version 2.0 (the "License"); you may # Licensed under the Apache License, Version 2.0 (the "License"); you may
@ -13,6 +13,4 @@
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
from nova import utils import nova.monkey_patch # noqa
utils.monkey_patch()

97
nova/monkey_patch.py Normal file
View File

@ -0,0 +1,97 @@
# Copyright 2010 United States Government as represented by the
# Administrator of the National Aeronautics and Space Administration.
# Copyright 2011 Justin Santa Barbara
# Copyright 2019 Red Hat, Inc.
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
"""Enable eventlet monkey patching."""
import os
def _monkey_patch():
# NOTE(mdbooth): Anything imported here will not be monkey patched. It is
# important to take care not to import anything here which requires monkey
# patching.
import eventlet
import sys
# NOTE(mdbooth): Imports only sys (2019-01-30). Other modules imported at
# runtime on execution of debugger.init().
from nova import debugger
# Note any modules with known monkey-patching issues which have been
# imported before monkey patching.
# urllib3: https://bugs.launchpad.net/nova/+bug/1808951
# oslo_context.context: https://bugs.launchpad.net/nova/+bug/1773102
problems = (set(['urllib3', 'oslo_context.context']) &
set(sys.modules.keys()))
# See https://bugs.launchpad.net/nova/+bug/1164822
# TODO(mdbooth): This feature was deprecated and removed in eventlet at
# some point but brought back in version 0.21.0, presumably because some
# users still required it to work round issues. However, there have been a
# number of greendns fixes in eventlet since then. Specifically, it looks
# as though the originally reported IPv6 issue may have been fixed in
# version 0.24.0. We should remove this when we can confirm that the
# original issue is fixed.
os.environ['EVENTLET_NO_GREENDNS'] = 'yes'
if debugger.enabled():
# turn off thread patching to enable the remote debugger
eventlet.monkey_patch(thread=False)
elif os.name == 'nt':
# for nova-compute running on Windows(Hyper-v)
# pipes don't support non-blocking I/O
eventlet.monkey_patch(os=False)
else:
eventlet.monkey_patch()
# NOTE(rpodolyaka): import oslo_service first, so that it makes eventlet
# hub use a monotonic clock to avoid issues with drifts of system time (see
# LP 1510234 for details)
# NOTE(mdbooth): This was fixed in eventlet 0.21.0. Remove when bumping
# eventlet version.
import oslo_service # noqa
eventlet.hubs.use_hub("oslo_service:service_hub")
# NOTE(mdbooth): Log here instead of earlier to avoid loading oslo logging
# before monkey patching.
# NOTE(mdbooth): Ideally we would raise an exception here, as this is
# likely to cause problems when executing nova code. However, some non-nova
# tools load nova only to extract metadata and do not execute it. Two
# examples are oslopolicy-policy-generator and sphinx, both of which can
# fail if we assert here. It is not ideal that these utilities are monkey
# patching at all, but we should not break them.
# TODO(mdbooth): If there is any way to reliably determine if we are being
# loaded in that kind of context without breaking existing callers, we
# should do it and bypass monkey patching here entirely.
if problems:
from oslo_log import log as logging
LOG = logging.getLogger(__name__)
LOG.warning("Modules with known eventlet monkey patching issues were "
"imported prior to eventlet monkey patching: %s. This "
"warning can usually be ignored if the caller is only "
"importing and not executing nova code.",
', '.join(problems))
# NOTE(mdbooth): This workaround is required to avoid breaking sphinx. See
# separate comment in doc/source/conf.py. It may also be useful for other
# non-nova utilities. Ideally the requirement for this workaround will be
# removed as soon as possible, so do not rely on, or extend it.
if (os.environ.get('OS_NOVA_DISABLE_EVENTLET_PATCHING', '').lower()
not in ('1', 'true', 'yes')):
_monkey_patch()

View File

@ -21,8 +21,7 @@ inline callbacks.
""" """
import eventlet # noqa import nova.monkey_patch # noqa
eventlet.monkey_patch()
import abc import abc
import copy import copy

View File

@ -20,6 +20,4 @@
:platform: Unix :platform: Unix
""" """
import eventlet import nova.monkey_patch # noqa
eventlet.monkey_patch()

View File

@ -49,10 +49,8 @@ from oslo_utils import timeutils
from oslo_utils import units from oslo_utils import units
import six import six
from six.moves import range from six.moves import range
from six.moves import reload_module
import nova.conf import nova.conf
from nova import debugger
from nova import exception from nova import exception
from nova.i18n import _, _LE, _LI, _LW from nova.i18n import _, _LE, _LI, _LW
import nova.network import nova.network
@ -1293,25 +1291,6 @@ def generate_hostid(host, project_id):
return "" return ""
def monkey_patch():
if debugger.enabled():
# turn off thread patching to enable the remote debugger
eventlet.monkey_patch(thread=False)
elif os.name == 'nt':
# for nova-compute running on Windows(Hyper-v)
# pipes don't support non-blocking I/O
eventlet.monkey_patch(os=False)
else:
eventlet.monkey_patch()
# NOTE(rgerganov): oslo.context is storing a global thread-local variable
# which keeps the request context for the current thread. If oslo.context
# is imported before calling monkey_patch(), then this thread-local won't
# be green. To workaround this, reload the module after calling
# monkey_patch()
reload_module(importutils.import_module('oslo_context.context'))
if six.PY2: if six.PY2:
nested_contexts = contextlib.nested nested_contexts = contextlib.nested
else: else: