Updated patcher.monkey_patch so it was easier to implement the util usecases. Deprecated everything in util that wasn't already deprecated.
This commit is contained in:
@@ -42,8 +42,12 @@ Monkeypatching the Standard Library
|
|||||||
The other way of greening an application is simply to monkeypatch the standard
|
The other way of greening an application is simply to monkeypatch the standard
|
||||||
library. This has the disadvantage of appearing quite magical, but the advantage of avoiding the late-binding problem.
|
library. This has the disadvantage of appearing quite magical, but the advantage of avoiding the late-binding problem.
|
||||||
|
|
||||||
.. function:: eventlet.patcher.monkey_patch(os=True, select=True, socket=True, thread=True, time=True)
|
.. function:: eventlet.patcher.monkey_patch(all=True, os=False, select=False, socket=False, thread=False, time=False):
|
||||||
|
By default, this function monkeypatches the key system modules by replacing their key elements with green equivalents. The keyword arguments afford some control over which modules are patched, in case that's important. If *all* is True, then all modules are patched regardless of the other arguments. If it's False, then the rest of the keyword arguments control patching of specific subsections of the standard library. Most patch the single module of the same name (e.g. time=True means that the time module is patched [time.sleep is patched by eventlet.sleep]). The exceptions to this rule are *socket*, which also patches the :mod:`ssl` module if present; and *thread*, which patches :mod:`thread`, :mod:`threading`, and :mod:`Queue`.
|
||||||
|
|
||||||
By default, this function monkeypatches the key system modules by replacing their key elements with green equivalents. The keyword arguments afford some control over which modules are patched, in case that's important. For almost all of them, they patch the single module of the same name (e.g. time=True means that the time module is patched [time.sleep is patched by eventlet.sleep]). The exceptions to this rule are *socket*, which also patches the :mod:`ssl` module if present; and *thread*, which patches both :mod:`thread` and :mod:`Queue`.
|
Here's an example of using monkey_patch to patch only a few modules::
|
||||||
|
|
||||||
It is important to call :func:`eventlet.patcher.monkey_patch` as early in the lifetime of the application as possible. Try to do it as one of the first lines in the main module. The reason for this is that sometimes there is a class that inherits from a class that needs to be greened -- e.g. a class that inherits from socket.socket -- and inheritance is done at import time, so therefore the monkeypatching should happen before the module that has the derived class is imported.
|
from eventlet import patcher
|
||||||
|
patcher.monkey_patch(all=False, socket=True, select=True)
|
||||||
|
|
||||||
|
It is important to call :func:`eventlet.patcher.monkey_patch` as early in the lifetime of the application as possible. Try to do it as one of the first lines in the main module. The reason for this is that sometimes there is a class that inherits from a class that needs to be greened -- e.g. a class that inherits from socket.socket -- and inheritance is done at import time, so therefore the monkeypatching should happen before the derived class is defined. It's safe to call monkey_patch multiple times.
|
||||||
@@ -97,26 +97,38 @@ def patch_function(func, *additional_modules):
|
|||||||
del sys.modules[name]
|
del sys.modules[name]
|
||||||
return patched
|
return patched
|
||||||
|
|
||||||
|
already_patched = {}
|
||||||
def monkey_patch(os=True, select=True, socket=True, thread=True, time=True):
|
def monkey_patch(all=True, os=False, select=False,
|
||||||
|
socket=False, thread=False, time=False):
|
||||||
"""Globally patches certain system modules to be greenthread-friendly.
|
"""Globally patches certain system modules to be greenthread-friendly.
|
||||||
|
|
||||||
The keyword arguments afford some control over which modules are patched.
|
The keyword arguments afford some control over which modules are patched.
|
||||||
For almost all of them, they patch the single module of the same name. The
|
If *all* is True, then all modules are patched regardless of the other
|
||||||
exceptions are socket, which also patches the ssl module if present; and
|
arguments. If it's False, then the rest of the keyword arguments control
|
||||||
thread, which patches thread and Queue.
|
patching of specific subsections of the standard library.
|
||||||
|
Most patch the single module of the same name (os, time,
|
||||||
|
select). The exceptions are socket, which also patches the ssl module if
|
||||||
|
present; and thread, which patches thread, threading, and Queue.
|
||||||
|
|
||||||
|
It's safe to call monkey_patch multiple times.
|
||||||
"""
|
"""
|
||||||
modules_to_patch = []
|
modules_to_patch = []
|
||||||
if os:
|
if all or os and not already_patched.get('os'):
|
||||||
modules_to_patch += _green_os_modules()
|
modules_to_patch += _green_os_modules()
|
||||||
if select:
|
already_patched['os'] = True
|
||||||
|
if all or select and not already_patched.get('select'):
|
||||||
modules_to_patch += _green_select_modules()
|
modules_to_patch += _green_select_modules()
|
||||||
if socket:
|
already_patched['select'] = True
|
||||||
|
if all or socket and not already_patched.get('socket'):
|
||||||
modules_to_patch += _green_socket_modules()
|
modules_to_patch += _green_socket_modules()
|
||||||
if thread:
|
already_patched['socket'] = True
|
||||||
|
if all or thread and not already_patched.get('thread'):
|
||||||
modules_to_patch += _green_thread_modules()
|
modules_to_patch += _green_thread_modules()
|
||||||
if time:
|
already_patched['thread'] = True
|
||||||
|
if all or time and not already_patched.get('time'):
|
||||||
modules_to_patch += _green_time_modules()
|
modules_to_patch += _green_time_modules()
|
||||||
|
already_patched['time'] = True
|
||||||
|
|
||||||
for name, mod in modules_to_patch:
|
for name, mod in modules_to_patch:
|
||||||
for attr in mod.__patched__:
|
for attr in mod.__patched__:
|
||||||
patched_attr = getattr(mod, attr, None)
|
patched_attr = getattr(mod, attr, None)
|
||||||
|
|||||||
121
eventlet/util.py
121
eventlet/util.py
@@ -2,10 +2,13 @@ import os
|
|||||||
import select
|
import select
|
||||||
import socket
|
import socket
|
||||||
import errno
|
import errno
|
||||||
|
import warnings
|
||||||
|
|
||||||
from eventlet import greenio
|
from eventlet import greenio
|
||||||
|
|
||||||
def g_log(*args):
|
def g_log(*args):
|
||||||
|
warnings.warn("eventlet.util.g_log is deprecated because we're pretty sure no one uses it. Send mail to eventletdev@lists.secondlife.com if you are actually using it.",
|
||||||
|
DeprecationWarning, stacklevel=2)
|
||||||
import sys
|
import sys
|
||||||
from eventlet.support import greenlets as greenlet
|
from eventlet.support import greenlets as greenlet
|
||||||
g_id = id(greenlet.getcurrent())
|
g_id = id(greenlet.getcurrent())
|
||||||
@@ -23,17 +26,11 @@ def g_log(*args):
|
|||||||
|
|
||||||
|
|
||||||
__original_socket__ = socket.socket
|
__original_socket__ = socket.socket
|
||||||
__original_gethostbyname__ = socket.gethostbyname
|
|
||||||
__original_getaddrinfo__ = socket.getaddrinfo
|
|
||||||
try:
|
|
||||||
__original_fromfd__ = socket.fromfd
|
|
||||||
__original_fork__ = os.fork
|
|
||||||
except AttributeError:
|
|
||||||
# Windows
|
|
||||||
__original_fromfd__ = None
|
|
||||||
__original_fork__ = None
|
|
||||||
|
|
||||||
def tcp_socket():
|
def tcp_socket():
|
||||||
|
warnings.warn("eventlet.util.tcp_sockt is deprecated."
|
||||||
|
"Please use the standard socket technique for this instead:"
|
||||||
|
"sock = socket.socket()",
|
||||||
|
DeprecationWarning, stacklevel=2)
|
||||||
s = __original_socket__(socket.AF_INET, socket.SOCK_STREAM)
|
s = __original_socket__(socket.AF_INET, socket.SOCK_STREAM)
|
||||||
return s
|
return s
|
||||||
|
|
||||||
@@ -68,81 +65,27 @@ except ImportError:
|
|||||||
connection.set_connect_state()
|
connection.set_connect_state()
|
||||||
return connection
|
return connection
|
||||||
|
|
||||||
socket_already_wrapped = False
|
|
||||||
def wrap_socket_with_coroutine_socket(use_thread_pool=None):
|
def wrap_socket_with_coroutine_socket(use_thread_pool=None):
|
||||||
global socket_already_wrapped
|
warnings.warn("eventlet.util.wrap_socket_with_coroutine_socket() is now "
|
||||||
if socket_already_wrapped:
|
"eventlet.patcher.monkey_patch(all=False, socket=True)",
|
||||||
return
|
DeprecationWarning, stacklevel=2)
|
||||||
|
from eventlet import patcher
|
||||||
import eventlet.green.socket
|
patcher.monkey_patch(all=False, socket=True)
|
||||||
socket.socket = eventlet.green.socket.socket
|
|
||||||
socket.ssl = eventlet.green.socket.ssl
|
|
||||||
try:
|
|
||||||
import ssl as _ssl
|
|
||||||
from eventlet.green import ssl
|
|
||||||
_ssl.wrap_socket = ssl.wrap_socket
|
|
||||||
except ImportError:
|
|
||||||
pass
|
|
||||||
|
|
||||||
if use_thread_pool is None:
|
|
||||||
# if caller doesn't specify, use the environment variable
|
|
||||||
# to decide whether to use tpool or not
|
|
||||||
use_thread_pool = os.environ.get("EVENTLET_TPOOL_GETHOSTBYNAME",
|
|
||||||
'').lower() == "yes"
|
|
||||||
if use_thread_pool:
|
|
||||||
try:
|
|
||||||
from eventlet import tpool
|
|
||||||
def new_gethostbyname(*args, **kw):
|
|
||||||
return tpool.execute(
|
|
||||||
__original_gethostbyname__, *args, **kw)
|
|
||||||
socket.gethostbyname = new_gethostbyname
|
|
||||||
|
|
||||||
def new_getaddrinfo(*args, **kw):
|
|
||||||
return tpool.execute(
|
|
||||||
__original_getaddrinfo__, *args, **kw)
|
|
||||||
socket.getaddrinfo = new_getaddrinfo
|
|
||||||
except ImportError:
|
|
||||||
pass # Windows
|
|
||||||
|
|
||||||
if __original_fromfd__ is not None:
|
|
||||||
def new_fromfd(*args, **kw):
|
|
||||||
return greenio.GreenSocket(__original_fromfd__(*args, **kw))
|
|
||||||
socket.fromfd = new_fromfd
|
|
||||||
|
|
||||||
socket_already_wrapped = True
|
|
||||||
|
|
||||||
|
|
||||||
__original_fdopen__ = os.fdopen
|
|
||||||
__original_read__ = os.read
|
|
||||||
__original_write__ = os.write
|
|
||||||
__original_waitpid__ = os.waitpid
|
|
||||||
## TODO wrappings for popen functions? not really needed since Process object exists?
|
|
||||||
|
|
||||||
|
|
||||||
pipes_already_wrapped = False
|
|
||||||
def wrap_pipes_with_coroutine_pipes():
|
def wrap_pipes_with_coroutine_pipes():
|
||||||
global pipes_already_wrapped
|
warnings.warn("eventlet.util.wrap_pipes_with_coroutine_pipes() is now "
|
||||||
if pipes_already_wrapped:
|
"eventlet.patcher.monkey_patch(all=False, os=True)",
|
||||||
return
|
DeprecationWarning, stacklevel=2)
|
||||||
from eventlet.green import greenos
|
from eventlet import patcher
|
||||||
os.fdopen = greenos.fdopen
|
patcher.monkey_patch(all=False, os=True)
|
||||||
os.read = greenos.read
|
|
||||||
os.write = greenos.write
|
|
||||||
os.waitpid = greenos.waitpid
|
|
||||||
|
|
||||||
__original_select__ = select.select
|
|
||||||
|
|
||||||
def wrap_select_with_coroutine_select():
|
def wrap_select_with_coroutine_select():
|
||||||
from eventlet.green import select as greenselect
|
warnings.warn("eventlet.util.wrap_select_with_coroutine_select() is now "
|
||||||
select.select = greenselect.select
|
"eventlet.patcher.monkey_patch(all=False, select=True)",
|
||||||
|
DeprecationWarning, stacklevel=2)
|
||||||
|
from eventlet import patcher
|
||||||
try:
|
patcher.monkey_patch(all=False, select=True)
|
||||||
import threading
|
|
||||||
__original_threadlocal__ = threading.local
|
|
||||||
except ImportError:
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
def wrap_threading_local_with_coro_local():
|
def wrap_threading_local_with_coro_local():
|
||||||
"""
|
"""
|
||||||
@@ -150,12 +93,22 @@ def wrap_threading_local_with_coro_local():
|
|||||||
Since greenlets cannot cross threads, so this should be semantically
|
Since greenlets cannot cross threads, so this should be semantically
|
||||||
identical to ``threadlocal.local``
|
identical to ``threadlocal.local``
|
||||||
"""
|
"""
|
||||||
from eventlet import api
|
warnings.warn("eventlet.util.wrap_threading_local_with_coro_local() is now "
|
||||||
from eventlet.corolocal import local
|
"eventlet.patcher.monkey_patch(all=False, thread=True) -- though"
|
||||||
threading.local = local
|
"note that more than just _local is patched now.",
|
||||||
|
DeprecationWarning, stacklevel=2)
|
||||||
|
|
||||||
|
from eventlet import patcher
|
||||||
|
patcher.monkey_patch(all=False, thread=True)
|
||||||
|
|
||||||
|
|
||||||
def socket_bind_and_listen(descriptor, addr=('', 0), backlog=50):
|
def socket_bind_and_listen(descriptor, addr=('', 0), backlog=50):
|
||||||
|
warnings.warn("eventlet.util.socket_bind_and_listen is deprecated."
|
||||||
|
"Please use the standard socket methodology for this instead:"
|
||||||
|
"sock.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR, 1)"
|
||||||
|
"sock.bind(addr)"
|
||||||
|
"sock.listen(backlog)",
|
||||||
|
DeprecationWarning, stacklevel=2)
|
||||||
set_reuse_addr(descriptor)
|
set_reuse_addr(descriptor)
|
||||||
descriptor.bind(addr)
|
descriptor.bind(addr)
|
||||||
descriptor.listen(backlog)
|
descriptor.listen(backlog)
|
||||||
@@ -163,6 +116,10 @@ def socket_bind_and_listen(descriptor, addr=('', 0), backlog=50):
|
|||||||
|
|
||||||
|
|
||||||
def set_reuse_addr(descriptor):
|
def set_reuse_addr(descriptor):
|
||||||
|
warnings.warn("eventlet.util.set_reuse_addr is deprecated."
|
||||||
|
"Please use the standard socket methodology for this instead:"
|
||||||
|
"sock.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR, 1)",
|
||||||
|
DeprecationWarning, stacklevel=2)
|
||||||
try:
|
try:
|
||||||
descriptor.setsockopt(
|
descriptor.setsockopt(
|
||||||
socket.SOL_SOCKET,
|
socket.SOL_SOCKET,
|
||||||
|
|||||||
Reference in New Issue
Block a user