summaryrefslogtreecommitdiff
path: root/eventlet
diff options
context:
space:
mode:
Diffstat (limited to 'eventlet')
-rw-r--r--eventlet/__init__.py12
-rw-r--r--eventlet/green/_socket_nodns.py16
-rw-r--r--eventlet/greenio/base.py27
-rw-r--r--eventlet/greenthread.py8
-rw-r--r--eventlet/hubs/__init__.py1
-rw-r--r--eventlet/support/__init__.py38
-rw-r--r--eventlet/timeout.py41
7 files changed, 114 insertions, 29 deletions
diff --git a/eventlet/__init__.py b/eventlet/__init__.py
index 4700261..0f57a1d 100644
--- a/eventlet/__init__.py
+++ b/eventlet/__init__.py
@@ -14,6 +14,7 @@ if os.environ.get('EVENTLET_IMPORT_VERSION_ONLY') != '1':
from eventlet import patcher
from eventlet import queue
from eventlet import semaphore
+ from eventlet import support
from eventlet import timeout
import greenlet
@@ -45,10 +46,15 @@ if os.environ.get('EVENTLET_IMPORT_VERSION_ONLY') != '1':
Timeout = timeout.Timeout
with_timeout = timeout.with_timeout
+ wrap_is_timeout = timeout.wrap_is_timeout
+ is_timeout = timeout.is_timeout
getcurrent = greenlet.greenlet.getcurrent
# deprecated
- TimeoutError = timeout.Timeout
- exc_after = greenthread.exc_after
- call_after_global = greenthread.call_after_global
+ TimeoutError, exc_after, call_after_global = (
+ support.wrap_deprecated(old, new)(fun) for old, new, fun in (
+ ('TimeoutError', 'Timeout', Timeout),
+ ('exc_after', 'greenthread.exc_after', greenthread.exc_after),
+ ('call_after_global', 'greenthread.call_after_global', greenthread.call_after_global),
+ ))
diff --git a/eventlet/green/_socket_nodns.py b/eventlet/green/_socket_nodns.py
index 8bfecfd..7dca20a 100644
--- a/eventlet/green/_socket_nodns.py
+++ b/eventlet/green/_socket_nodns.py
@@ -1,17 +1,19 @@
__socket = __import__('socket')
__all__ = __socket.__all__
-__patched__ = ['fromfd', 'socketpair', 'ssl', 'socket']
+__patched__ = ['fromfd', 'socketpair', 'ssl', 'socket', 'timeout']
-from eventlet.patcher import slurp_properties
-slurp_properties(__socket, globals(),
- ignore=__patched__, srckeys=dir(__socket))
+import eventlet.patcher
+eventlet.patcher.slurp_properties(__socket, globals(), ignore=__patched__, srckeys=dir(__socket))
os = __import__('os')
import sys
-from eventlet.hubs import get_hub
-from eventlet.greenio import GreenSocket as socket
-from eventlet.greenio import _GLOBAL_DEFAULT_TIMEOUT
+from eventlet import greenio
+
+
+socket = greenio.GreenSocket
+_GLOBAL_DEFAULT_TIMEOUT = greenio._GLOBAL_DEFAULT_TIMEOUT
+timeout = greenio.socket_timeout
try:
__original_fromfd__ = __socket.fromfd
diff --git a/eventlet/greenio/base.py b/eventlet/greenio/base.py
index 7cb68c1..042f7d8 100644
--- a/eventlet/greenio/base.py
+++ b/eventlet/greenio/base.py
@@ -13,6 +13,7 @@ __all__ = [
'GreenSocket', '_GLOBAL_DEFAULT_TIMEOUT', 'set_nonblocking',
'SOCKET_BLOCKING', 'SOCKET_CLOSED', 'CONNECT_ERR', 'CONNECT_SUCCESS',
'shutdown_safe', 'SSL',
+ 'socket_timeout',
]
BUFFER_SIZE = 4096
@@ -27,6 +28,9 @@ if six.PY2:
_original_socket = eventlet.patcher.original('socket').socket
+socket_timeout = eventlet.timeout.wrap_is_timeout(socket.timeout)
+
+
def socket_connect(descriptor, address):
"""
Attempts to connect to the address, returns the descriptor if it succeeds,
@@ -210,14 +214,14 @@ class GreenSocket(object):
if self.act_non_blocking:
return self.fd.accept()
fd = self.fd
+ _timeout_exc = socket_timeout('timed out')
while True:
res = socket_accept(fd)
if res is not None:
client, addr = res
set_nonblocking(client)
return type(self)(client), addr
- self._trampoline(fd, read=True, timeout=self.gettimeout(),
- timeout_exc=socket.timeout("timed out"))
+ self._trampoline(fd, read=True, timeout=self.gettimeout(), timeout_exc=_timeout_exc)
def _mark_as_closed(self):
""" Mark this socket as being closed """
@@ -233,6 +237,7 @@ class GreenSocket(object):
if self.act_non_blocking:
return self.fd.connect(address)
fd = self.fd
+ _timeout_exc = socket_timeout('timed out')
if self.gettimeout() is None:
while not socket_connect(fd, address):
try:
@@ -246,10 +251,10 @@ class GreenSocket(object):
if socket_connect(fd, address):
return
if time.time() >= end:
- raise socket.timeout("timed out")
+ raise _timeout_exc
+ timeout = end - time.time()
try:
- self._trampoline(fd, write=True, timeout=end - time.time(),
- timeout_exc=socket.timeout("timed out"))
+ self._trampoline(fd, write=True, timeout=timeout, timeout_exc=_timeout_exc)
except IOClosed:
# ... we need some workable errno here.
raise socket.error(errno.EBADFD)
@@ -270,14 +275,15 @@ class GreenSocket(object):
return errno.EBADFD
else:
end = time.time() + self.gettimeout()
+ timeout_exc = socket.timeout(errno.EAGAIN)
while True:
try:
if socket_connect(fd, address):
return 0
if time.time() >= end:
- raise socket.timeout(errno.EAGAIN)
+ raise timeout_exc
self._trampoline(fd, write=True, timeout=end - time.time(),
- timeout_exc=socket.timeout(errno.EAGAIN))
+ timeout_exc=timeout_exc)
socket_checkerr(fd)
except socket.error as ex:
return get_errno(ex)
@@ -316,7 +322,7 @@ class GreenSocket(object):
self.fd,
read=True,
timeout=self.gettimeout(),
- timeout_exc=socket.timeout("timed out"))
+ timeout_exc=socket_timeout('timed out'))
def _recv_loop(self, recv_meth, empty_val, *args):
fd = self.fd
@@ -366,7 +372,8 @@ class GreenSocket(object):
if self.act_non_blocking:
return send_method(data, *args)
- while 1:
+ _timeout_exc = socket_timeout('timed out')
+ while True:
try:
return send_method(data, *args)
except socket.error as e:
@@ -376,7 +383,7 @@ class GreenSocket(object):
try:
self._trampoline(self.fd, write=True, timeout=self.gettimeout(),
- timeout_exc=socket.timeout("timed out"))
+ timeout_exc=_timeout_exc)
except IOClosed:
raise socket.error(errno.ECONNRESET, 'Connection closed by another thread')
diff --git a/eventlet/greenthread.py b/eventlet/greenthread.py
index 921d7a9..c0f2982 100644
--- a/eventlet/greenthread.py
+++ b/eventlet/greenthread.py
@@ -3,6 +3,7 @@ import sys
from eventlet import event
from eventlet import hubs
+from eventlet import support
from eventlet import timeout
from eventlet.hubs import timer
from eventlet.support import greenlets as greenlet, six
@@ -144,8 +145,11 @@ def exc_after(seconds, *throw_args):
return hub.schedule_call_local(seconds, getcurrent().throw, *throw_args)
# deprecate, remove
-TimeoutError = timeout.Timeout
-with_timeout = timeout.with_timeout
+TimeoutError, with_timeout = (
+ support.wrap_deprecated(old, new)(fun) for old, new, fun in (
+ ('greenthread.TimeoutError', 'Timeout', timeout.Timeout),
+ ('greenthread.with_timeout', 'with_timeout', timeout.with_timeout),
+ ))
def _spawn_n(seconds, func, args, kwargs):
diff --git a/eventlet/hubs/__init__.py b/eventlet/hubs/__init__.py
index 9f72c16..879ec9a 100644
--- a/eventlet/hubs/__init__.py
+++ b/eventlet/hubs/__init__.py
@@ -118,6 +118,7 @@ def get_hub():
return hub
+# Lame middle file import because complex dependencies in import graph
from eventlet import timeout
diff --git a/eventlet/support/__init__.py b/eventlet/support/__init__.py
index 4c2b75d..b311c8a 100644
--- a/eventlet/support/__init__.py
+++ b/eventlet/support/__init__.py
@@ -1,9 +1,15 @@
+import inspect
+import functools
import sys
-from contextlib import contextmanager
+import warnings
+import contextlib
from eventlet.support import greenlets, six
+_MISSING = object()
+
+
def get_errno(exc):
""" Get the error code out of socket.error objects.
socket.error in <2.5 does not have errno attribute
@@ -43,7 +49,8 @@ else:
PY33 = sys.version_info[:2] == (3, 3)
-@contextmanager
+
+@contextlib.contextmanager
def capture_stderr():
stream = six.StringIO()
original = sys.stderr
@@ -53,3 +60,30 @@ def capture_stderr():
finally:
sys.stderr = original
stream.seek(0)
+
+
+def wrap_deprecated(old, new):
+ def _resolve(s):
+ return 'eventlet.'+s if '.' not in s else s
+ msg = '''\
+{old} is deprecated and will be removed in next version. Use {new} instead.
+Autoupgrade: fgrep -rl '{old}' . |xargs -t sed --in-place='' -e 's/{old}/{new}/'
+'''.format(old=_resolve(old), new=_resolve(new))
+
+ def wrapper(base):
+ klass = None
+ if inspect.isclass(base):
+ klass = base
+ base = klass.__init__
+
+ @functools.wraps(base)
+ def wrapped(*a, **kw):
+ warnings.warn(msg, DeprecationWarning, stacklevel=5)
+ return base(*a, **kw)
+
+ if klass is not None:
+ klass.__init__ = wrapped
+ return klass
+
+ return wrapped
+ return wrapper
diff --git a/eventlet/timeout.py b/eventlet/timeout.py
index f45c6d1..f431871 100644
--- a/eventlet/timeout.py
+++ b/eventlet/timeout.py
@@ -20,13 +20,16 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.from eventlet.support import greenlets as greenlet
+import functools
+import inspect
+
+import eventlet
from eventlet.support import greenlets as greenlet
from eventlet.hubs import get_hub
-__all__ = ['Timeout',
- 'with_timeout']
+__all__ = ['Timeout', 'with_timeout', 'wrap_is_timeout', 'is_timeout']
-_NONE = object()
+_MISSING = object()
# deriving from BaseException so that "except Exception as e" doesn't catch
# Timeout exceptions.
@@ -128,20 +131,48 @@ class Timeout(BaseException):
if value is self and self.exception is False:
return True
+ @property
+ def is_timeout(self):
+ return True
+
def with_timeout(seconds, function, *args, **kwds):
"""Wrap a call to some (yielding) function with a timeout; if the called
function fails to return before the timeout, cancel it and return a flag
value.
"""
- timeout_value = kwds.pop("timeout_value", _NONE)
+ timeout_value = kwds.pop("timeout_value", _MISSING)
timeout = Timeout(seconds)
try:
try:
return function(*args, **kwds)
except Timeout as ex:
- if ex is timeout and timeout_value is not _NONE:
+ if ex is timeout and timeout_value is not _MISSING:
return timeout_value
raise
finally:
timeout.cancel()
+
+
+def wrap_is_timeout(base):
+ '''Adds `.is_timeout=True` attribute to objects returned by `base()`.
+
+ When `base` is class, attribute is added as read-only property. Returns `base`.
+ Otherwise, it returns a function that sets attribute on result of `base()` call.
+
+ Wrappers make best effort to be transparent.
+ '''
+ if inspect.isclass(base):
+ base.is_timeout = property(lambda _: True)
+ return base
+
+ @functools.wraps(base)
+ def fun(*args, **kwargs):
+ ex = base(*args, **kwargs)
+ ex.is_timeout = True
+ return ex
+ return fun
+
+
+def is_timeout(obj):
+ return bool(getattr(obj, 'is_timeout', False))