def _is_contextvars_broken(): # type: () -> bool """ Returns whether gevent/eventlet have patched the stdlib in a way where thread locals are now more "correct" than contextvars. """ try: from gevent.monkey import is_object_patched # type: ignore if is_object_patched("threading", "local"): # Gevent 20.5 is able to patch both thread locals and contextvars, # in that case all is good. if is_object_patched("contextvars", "ContextVar"): return False return True except ImportError: pass try: from eventlet.patcher import is_monkey_patched # type: ignore if is_monkey_patched("thread"): return True except ImportError: pass return False
def __init__(self): super(_GreenFuture, self).__init__() # NOTE(harlowja): replace the built-in condition with a greenthread # compatible one so that when getting the result of this future the # functions will correctly yield to eventlet. If this is not done then # waiting on the future never actually causes the greenthreads to run # and thus you wait for infinity. if not patcher.is_monkey_patched('threading'): self._condition = gthreading.Condition()
def __init__(self, *args, **kwargs): if is_monkey_patched('socket'): # If we are running in a monkey patched environment # use eventlet's GreenConnection -- it handles eventlet's # non-blocking sockets correctly. Connection = GreenConnection else: Connection = OpenSSL.SSL.Connection self.connection = Connection(*args, **kwargs)
def test_eventlet_thread_monkeypatched(): eventlet.monkey_patch(thread=True) assert is_monkey_patched("thread") execution_context = zuqa.context.init_execution_context() # Should always use ThreadLocalContext when eventlet has patched # threading.local assert isinstance(execution_context, ThreadLocalContext)
def test_transaction_with_eventlet(sending_zuqa_client): assert is_monkey_patched(os) transaction = sending_zuqa_client.begin_transaction("test") with zuqa.capture_span("bla"): pass sending_zuqa_client.end_transaction("test", "OK") sending_zuqa_client.close() assert len(sending_zuqa_client.httpserver.requests) == 1 assert sending_zuqa_client.httpserver.payloads[0][1][constants.SPAN] assert sending_zuqa_client.httpserver.payloads[0][2][constants.TRANSACTION]
def _fetch_current_thread_functor(): # Until https://github.com/eventlet/eventlet/issues/172 is resolved # or addressed we have to use complicated workaround to get a object # that will not be recycled; the usage of threading.current_thread() # doesn't appear to currently be monkey patched and therefore isn't # reliable to use (and breaks badly when used as all threads share # the same current_thread() object)... if eventlet is not None and eventlet_patcher is not None: if eventlet_patcher.is_monkey_patched('thread'): return eventlet.getcurrent return threading.current_thread
def check_evenlet_monkey_patch(raise_exc=True): if not patcher.is_monkey_patched('socket'): # 随便选一个检测标志 if raise_exc: warnings.warn( f'检测到没有打 evenlet 包的猴子补丁 ,请在起始脚本文件首行加上 import eventlet;eventlet.monkey_patch(all=True) ' ) raise Exception( '检测到没有打 evenlet 包的猴子补丁 ,请在起始脚本文件首行加上 import eventlet;eventlet.monkey_patch(all=True)' ) else: return 1
def test_function_replace(self): old_socket = sys.modules.get('socket') old_socket_id = id(old_socket.create_connection) monkey_patch(socket=True) new_socket = sys.modules.get('socket') new_socket_id = id(new_socket.create_connection) # patch前后create_connection函数被替换了 self.assertNotEqual(old_socket_id, new_socket_id) self.assertEqual(True, is_monkey_patched(socket))
def get_future_executor(): """Future executor factory method.""" global _executor if _executor: return _executor executor = defaultFutureExecutor environment = detect_environment() if environment == 'eventlet': from eventlet.patcher import is_monkey_patched if is_monkey_patched('os') or is_monkey_patched('select'): raise RuntimeError( "it currently doesn't support coroutine execution under " "eventlet's heavy monkey patch.") executor = eventletFutureExecutor elif environment == 'gevent': executor = geventFutureExecutor _executor = executor return _executor
def initialize(self, server): super(KombuManager, self).initialize(server) monkey_patched = True if server.async_mode == 'eventlet': from eventlet.patcher import is_monkey_patched monkey_patched = is_monkey_patched('socket') elif 'gevent' in server.async_mode: from gevent.monkey import is_module_patched monkey_patched = is_module_patched('socket') if not monkey_patched: raise RuntimeError('Redis requires a monkey patched socket ' 'library to work with ' + server.async_mode)
def _fetch_current_thread_functor(): # Until https://github.com/eventlet/eventlet/issues/172 is resolved # or addressed we have to use complicated workaround to get a object # that will not be recycled; the usage of threading.current_thread() # doesn't appear to currently be monkey patched and therefore isn't # reliable to use (and breaks badly when used as all threads share # the same current_thread() object)... try: import eventlet from eventlet import patcher green_threaded = patcher.is_monkey_patched('thread') except ImportError: green_threaded = False if green_threaded: return lambda: eventlet.getcurrent() else: return lambda: threading.current_thread()
def _poll_events(callback): if patcher.is_monkey_patched('thread'): listen = functools.partial(tpool.execute, listener, self._VNIC_LISTENER_TIMEOUT_MS) else: listen = functools.partial(listener, self._VNIC_LISTENER_TIMEOUT_MS) while True: # Retrieve one by one all the events that occurred in # the checked interval. try: event = listen() callback(event.ElementName) except wmi.x_wmi_timed_out: # no new event published. pass
def monitor_vm_failover(self, callback, event_timeout_ms=_WMI_EVENT_TIMEOUT_MS): """Creates a monitor to check for new WMI MSCluster_Resource events. This method will poll the last _WMI_EVENT_CHECK_INTERVAL + 1 seconds for new events and listens for _WMI_EVENT_TIMEOUT_MS miliseconds, since listening is a thread blocking action. Any event object caught will then be processed. """ # TODO(lpetrut): mark this method as private once compute-hyperv # stops using it. We should also remove the instance '_watcher' # attribute since we end up spawning unused event listeners. vm_name = None new_host = None try: # wait for new event for _WMI_EVENT_TIMEOUT_MS miliseconds. if patcher.is_monkey_patched('thread'): wmi_object = tpool.execute(self._watcher, event_timeout_ms) else: wmi_object = self._watcher(event_timeout_ms) old_host = wmi_object.previous.OwnerNode new_host = wmi_object.OwnerNode # wmi_object.Name field is of the form: # 'Virtual Machine nova-instance-template' # wmi_object.Name filed is a key and as such is not affected # by locale, so it will always be 'Virtual Machine' match = self._instance_name_regex.search(wmi_object.Name) if match: vm_name = match.group(1) if vm_name: try: callback(vm_name, old_host, new_host) except Exception: LOG.exception( _LE("Exception during failover callback.")) except exceptions.x_wmi_timed_out: pass
def run(self, handler): from eventlet import wsgi, listen, patcher if not patcher.is_monkey_patched(os): msg = "Bottle requires eventlet.monkey_patch() (before import)" raise RuntimeError(msg) socket_args = {} for arg in ('backlog', 'family'): try: socket_args[arg] = self.options.pop(arg) except KeyError: pass address = (self.host, self.port) try: wsgi.server(listen(address, **socket_args), handler, log_output=(not self.quiet)) except TypeError: # Fallback, if we have old version of eventlet wsgi.server(listen(address), handler)
def _is_threading_local_monkey_patched(): # type: () -> bool try: from gevent.monkey import is_object_patched # type: ignore if is_object_patched("threading", "local"): return True except ImportError: pass try: from eventlet.patcher import is_monkey_patched # type: ignore if is_monkey_patched("thread"): return True except ImportError: pass return False
def threading_local_monkey_patched(): # Returns True if thread locals have been patched by either gevent of # eventlet try: from gevent.monkey import is_object_patched except ImportError: pass else: if is_object_patched("_threading", "local"): return True try: from eventlet.patcher import is_monkey_patched except ImportError: pass else: if is_monkey_patched("thread"): return True return False
def _is_contextvars_broken(): # type: () -> bool """ Returns whether gevent/eventlet have patched the stdlib in a way where thread locals are now more "correct" than contextvars. """ try: import gevent # type: ignore from gevent.monkey import is_object_patched # type: ignore # Get the MAJOR and MINOR version numbers of Gevent version_tuple = tuple([ int(part) for part in re.split(r"a|b|rc|\.", gevent.__version__)[:2] ]) if is_object_patched("threading", "local"): # Gevent 20.9.0 depends on Greenlet 0.4.17 which natively handles switching # context vars when greenlets are switched, so, Gevent 20.9.0+ is all fine. # Ref: https://github.com/gevent/gevent/blob/83c9e2ae5b0834b8f84233760aabe82c3ba065b4/src/gevent/monkey.py#L604-L609 # Gevent 20.5, that doesn't depend on Greenlet 0.4.17 with native support # for contextvars, is able to patch both thread locals and contextvars, in # that case, check if contextvars are effectively patched. if ( # Gevent 20.9.0+ (sys.version_info >= (3, 7) and version_tuple >= (20, 9)) # Gevent 20.5.0+ or Python < 3.7 or (is_object_patched("contextvars", "ContextVar"))): return False return True except ImportError: pass try: from eventlet.patcher import is_monkey_patched # type: ignore if is_monkey_patched("thread"): return True except ImportError: pass return False
def _poll_events(callback): if patcher.is_monkey_patched('thread'): listen = functools.partial(tpool.execute, listener, self._VNIC_LISTENER_TIMEOUT_MS) else: listen = functools.partial(listener, self._VNIC_LISTENER_TIMEOUT_MS) while True: # Retrieve one by one all the events that occurred in # the checked interval. try: event = listen() if event.ElementName: callback(event.ElementName) else: LOG.warning("Ignoring port event. " "The port name is missing.") except exceptions.x_wmi_timed_out: # no new event published. pass
def _handle_events(callback): if patcher.is_monkey_patched('thread'): # Retrieve one by one all the events that occurred in # the checked interval. # # We use eventlet.tpool for retrieving the events in # order to avoid issues caused by greenthread/thread # communication. Note that PyMI must use the unpatched # threading module. listen = functools.partial(tpool.execute, listener, event_timeout) else: listen = functools.partial(listener, event_timeout) while True: try: event = listen() vm_name = event.ElementName vm_state = event.EnabledState vm_power_state = self.get_vm_power_state(vm_state) try: callback(vm_name, vm_power_state) except Exception: err_msg = _LE("Executing VM power state change event " "callback failed. " "VM name: %(vm_name)s, " "VM power state: %(vm_power_state)s.") LOG.exception( err_msg, dict(vm_name=vm_name, vm_power_state=vm_power_state)) except exceptions.x_wmi_timed_out: pass except Exception: LOG.exception( _LE("The VM power state change event listener " "encountered an unexpected exception.")) time.sleep(event_timeout / 1000)
def monitor_vm_failover(self, callback): """Creates a monitor to check for new WMI MSCluster_Resource events. This method will poll the last _WMI_EVENT_CHECK_INTERVAL + 1 seconds for new events and listens for _WMI_EVENT_TIMEOUT_MS miliseconds, since listening is a thread blocking action. Any event object caught will then be processed. """ vm_name = None new_host = None try: # wait for new event for _WMI_EVENT_TIMEOUT_MS miliseconds. if patcher.is_monkey_patched('thread'): wmi_object = tpool.execute(self._watcher, self._WMI_EVENT_TIMEOUT_MS) else: wmi_object = self._watcher(self._WMI_EVENT_TIMEOUT_MS) old_host = wmi_object.previous.OwnerNode new_host = wmi_object.OwnerNode # wmi_object.Name field is of the form: # 'Virtual Machine nova-instance-template' # wmi_object.Name filed is a key and as such is not affected # by locale, so it will always be 'Virtual Machine' match = self._instance_name_regex.search(wmi_object.Name) if match: vm_name = match.group(1) if vm_name: try: callback(vm_name, old_host, new_host) except Exception: LOG.exception( _LE("Exception during failover callback.")) except exceptions.x_wmi_timed_out: pass
def _is_contextvars_broken(): # type: () -> bool try: from gevent.monkey import is_object_patched # type: ignore if is_object_patched("threading", "local"): if is_object_patched("contextvars", "ContextVar"): return False return True except ImportError: pass try: from eventlet.patcher import is_monkey_patched # type: ignore if is_monkey_patched("thread"): return True except ImportError: pass return False
def _handle_events(callback): if patcher.is_monkey_patched('thread'): # Retrieve one by one all the events that occurred in # the checked interval. # # We use eventlet.tpool for retrieving the events in # order to avoid issues caused by greenthread/thread # communication. Note that PyMI must use the unpatched # threading module. listen = functools.partial(tpool.execute, listener, event_timeout) else: listen = functools.partial(listener, event_timeout) while True: try: event = listen() vm_name = event.ElementName vm_state = event.EnabledState vm_power_state = self.get_vm_power_state(vm_state) try: callback(vm_name, vm_power_state) except Exception: err_msg = _LE("Executing VM power state change event " "callback failed. " "VM name: %(vm_name)s, " "VM power state: %(vm_power_state)s.") LOG.exception(err_msg, dict(vm_name=vm_name, vm_power_state=vm_power_state)) except wmi.x_wmi_timed_out: pass except Exception: LOG.exception( _LE("The VM power state change event listener " "encountered an unexpected exception.")) time.sleep(event_timeout / 1000)
def _detect_greenthread_environment() -> str: """ Detect if eventlet or gevent are in use. :return: 'eventlet', 'gevent', or 'default' (neither environment detected) """ if "eventlet" in sys.modules: with contextlib.suppress(ImportError): from eventlet.patcher import is_monkey_patched # noqa: WPS433 import socket # noqa: WPS433 if is_monkey_patched(socket): return "eventlet" if "gevent" in sys.modules: with contextlib.suppress(ImportError): from gevent import socket as gsocket # noqa: WPS433 import socket # noqa: WPS433, WPS440 if socket.socket is gsocket.socket: # type: ignore return "gevent" return "default"
def monitor_vm_failover(self, callback): """Creates a monitor to check for new WMI MSCluster_Resource events. This method will poll the last _WMI_EVENT_CHECK_INTERVAL + 1 seconds for new events and listens for _WMI_EVENT_TIMEOUT_MS miliseconds, since listening is a thread blocking action. Any event object caught will then be processed. """ vm_name = None new_host = None try: # wait for new event for _WMI_EVENT_TIMEOUT_MS miliseconds. if patcher.is_monkey_patched('thread'): wmi_object = tpool.execute(self._watcher, self._WMI_EVENT_TIMEOUT_MS) else: wmi_object = self._watcher(self._WMI_EVENT_TIMEOUT_MS) old_host = wmi_object.previous.OwnerNode new_host = wmi_object.OwnerNode # wmi_object.Name field is of the form: # 'Virtual Machine nova-instance-template' # wmi_object.Name filed is a key and as such is not affected # by locale, so it will always be 'Virtual Machine' match = self._instance_name_regex.search(wmi_object.Name) if match: vm_name = match.group(1) if vm_name: try: callback(vm_name, old_host, new_host) except Exception: LOG.exception(_LE("Exception during failover callback.")) except wmi.x_wmi_timed_out: pass
if not hasattr(urlparse, "parse_qsl"): import cgi urlparse.parse_qsl = cgi.parse_qsl import OpenSSL from glanceclient import exc from glanceclient.common import utils from glanceclient.openstack.common import strutils try: from eventlet import patcher # Handle case where we are running in a monkey patched environment if patcher.is_monkey_patched("socket"): from eventlet.green.httplib import HTTPSConnection from eventlet.green.OpenSSL.SSL import GreenConnection as Connection from eventlet.greenio import GreenSocket # TODO(mclaren): A getsockopt workaround: see 'getsockopt' doc string GreenSocket.getsockopt = utils.getsockopt else: raise ImportError except ImportError: from httplib import HTTPSConnection from OpenSSL.SSL import Connection as Connection LOG = logging.getLogger(__name__) USER_AGENT = "python-glanceclient"
def _fetch_current_thread_functor(): if eventlet is not None and eventlet_patcher is not None: if eventlet_patcher.is_monkey_patched('thread'): return eventlet.getcurrent return threading.current_thread
def _using_eventlet_green_select(): return eventlet_patcher.is_monkey_patched(select)
from requests.packages.urllib3 import poolmanager except ImportError: from urllib3 import connectionpool from urllib3 import poolmanager from oslo_utils import encodeutils import six # NOTE(jokke): simplified transition to py3, behaves like py2 xrange from six.moves import range from glanceclient.common import utils try: from eventlet import patcher # Handle case where we are running in a monkey patched environment if patcher.is_monkey_patched('socket'): from eventlet.green.httplib import HTTPSConnection from eventlet.green.OpenSSL.SSL import GreenConnection as Connection from eventlet.greenio import GreenSocket # TODO(mclaren): A getsockopt workaround: see 'getsockopt' doc string GreenSocket.getsockopt = utils.getsockopt else: raise ImportError except ImportError: try: from httplib import HTTPSConnection except ImportError: from http.client import HTTPSConnection from OpenSSL.SSL import Connection as Connection from glanceclient import exc
import struct import weakref import mi from mi import mi_error import pbr.version try: import eventlet from eventlet import patcher from eventlet import tpool # If eventlet is installed and the 'thread' module is patched, we'll make # sure that other greenthreads will not be blocked while WMI operations # are performed by using tpool. # This behavior can be disabled by using the following flag. EVENTLET_NONBLOCKING_MODE_ENABLED = patcher.is_monkey_patched('thread') except ImportError: eventlet = None EVENTLET_NONBLOCKING_MODE_ENABLED = False __all__ = ['__version__'] version_info = pbr.version.VersionInfo('PyMI') try: __version__ = version_info.version_string() except AttributeError: __version__ = None def avoid_blocking_call(f): # Performs blocking calls in a different thread using tpool.execute
from . import delta from .delta import DeltaList from .delta import DeltaItem from .tool import comp_lzma from .progressbar import AnimatedProgressBar from .package import VMOverlayPackage from . import compression from . import process_manager from . import qmp_af_unix from . import log as logging # to work with OpenStack's eventlet try: from eventlet import patcher if patcher.is_monkey_patched("thread"): native_threading = patcher.original("threading") else: raise ImportError("threading is not monkey-patched") except ImportError as e: import threading native_threading = threading LOG = logging.getLogger(__name__) # This is only for experiemental purpose. # It is used to measure the time for changing network BW or CPU cores at the # right time. _handoff_start_time = [sys.maxsize]
from .package import VMOverlayPackage from . import delta from .delta import DeltaList from .delta import DeltaItem from .tool import comp_lzma from .progressbar import AnimatedProgressBar from .package import VMOverlayPackage from . import compression from . import process_manager from . import qmp_af_unix from . import log as logging # to work with OpenStack's eventlet try: from eventlet import patcher if patcher.is_monkey_patched("thread"): native_threading = patcher.original("threading") else: raise ImportError("threading is not monkey-patched") except ImportError as e: import threading native_threading = threading LOG = logging.getLogger(__name__) # This is only for experiemental purpose. # It is used to measure the time for changing network BW or CPU cores at the # right time. _handoff_start_time = [sys.maxsize]
try: from requests.packages.urllib3 import connectionpool except ImportError: from urllib3 import connectionpool from oslo_utils import encodeutils import six # NOTE(jokke): simplified transition to py3, behaves like py2 xrange from six.moves import range from daisyclient.common import utils try: from eventlet import patcher # Handle case where we are running in a monkey patched environment if patcher.is_monkey_patched('socket'): from eventlet.green.httplib import HTTPSConnection from eventlet.green.OpenSSL.SSL import GreenConnection as Connection from eventlet.greenio import GreenSocket # TODO(mclaren): A getsockopt workaround: see 'getsockopt' doc string GreenSocket.getsockopt = utils.getsockopt else: raise ImportError except ImportError: try: from httplib import HTTPSConnection except ImportError: from http.client import HTTPSConnection from OpenSSL.SSL import Connection as Connection
try: from gevent.monkey import is_object_patched except ImportError: pass else: if is_object_patched("threading", "local") and not is_object_patched( "contextvars", "ContextVar"): raise _CannotUseContextVar() # Eventlet does not patch contextvars at all try: from eventlet.patcher import is_monkey_patched except ImportError: pass else: if is_monkey_patched( "thread") and not is_monkey_patched("contextvars"): raise _CannotUseContextVar() except (ImportError, _CannotUseContextVar): class ContextVar: # type: ignore """A fake ContextVar for Python3.6 based on the ident function.""" def __init__(self, _name): self.ident_func = get_ident self.storage = {} def get(self, default): return self.storage.get(self.ident_func(), default) def set(self, value): self.storage[self.ident_func()] = value
import struct from eventlet import patcher try: import OpenSSL except ImportError: OpenSSL = None from oslo_log import log as logging import six from six.moves import http_client from six.moves import urllib from cinder.i18n import _, _LI # Handle case where we are running in a monkey patched environment if OpenSSL and patcher.is_monkey_patched('socket'): from eventlet.green.OpenSSL import SSL try: import pywbem pywbemAvailable = True except ImportError: pywbemAvailable = False LOG = logging.getLogger(__name__) def to_bytes(s): if isinstance(s, six.string_types): return six.b(s)
import struct from eventlet import patcher try: import OpenSSL except ImportError: OpenSSL = None from oslo_log import log as logging import six from six.moves import http_client from six.moves import urllib from cinder.i18n import _ # Handle case where we are running in a monkey patched environment if OpenSSL and patcher.is_monkey_patched('socket'): from eventlet.green.OpenSSL import SSL try: import pywbem pywbemAvailable = True except ImportError: pywbemAvailable = False LOG = logging.getLogger(__name__) def to_bytes(s): if isinstance(s, six.string_types): return six.b(s) else:
import six import struct import weakref import mi from mi import mi_error try: import eventlet from eventlet import patcher from eventlet import tpool # If eventlet is installed and the 'thread' module is patched, we'll make # sure that other greenthreads will not be blocked while WMI operations # are performed by using tpool. # This behavior can be disabled by using the following flag. EVENTLET_NONBLOCKING_MODE_ENABLED = patcher.is_monkey_patched('thread') except ImportError: eventlet = None EVENTLET_NONBLOCKING_MODE_ENABLED = False def avoid_blocking_call(f): # Performs blocking calls in a different thread using tpool.execute # when called from a greenthread. # Note that eventlet.getcurrent will always return a greenlet object. # Still, in case of a greenthread, the parent greenlet will always be the # hub loop greenlet. def wrapper(*args, **kwargs): if (EVENTLET_NONBLOCKING_MODE_ENABLED and eventlet.getcurrent().parent): return tpool.execute(f, *args, **kwargs)