diff options
| author | Sergey Shepelev <temotor@gmail.com> | 2016-12-22 04:35:14 +0300 |
|---|---|---|
| committer | Sergey Shepelev <temotor@gmail.com> | 2016-12-22 04:35:14 +0300 |
| commit | 66ad70c5189310db5c5b8916908581b391463343 (patch) | |
| tree | 23595394d6f68c79d3c268b3eddc5b85e5ec8847 /eventlet | |
| parent | f190122026463b28c587760c04b4d306ba61430e (diff) | |
| download | eventlet-error-is-timeout.tar.gz | |
Diffstat (limited to 'eventlet')
| -rw-r--r-- | eventlet/__init__.py | 2 | ||||
| -rw-r--r-- | eventlet/green/_socket_nodns.py | 16 | ||||
| -rw-r--r-- | eventlet/greenio/base.py | 24 | ||||
| -rw-r--r-- | eventlet/timeout.py | 22 |
4 files changed, 46 insertions, 18 deletions
diff --git a/eventlet/__init__.py b/eventlet/__init__.py index efbdbe6..929f0d9 100644 --- a/eventlet/__init__.py +++ b/eventlet/__init__.py @@ -23,6 +23,8 @@ 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 GreenPool = greenpool.GreenPool GreenPile = greenpool.GreenPile 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..107eb86 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,11 @@ if six.PY2: _original_socket = eventlet.patcher.original('socket').socket +socket_timeout = eventlet.timeout.wrap_is_timeout(socket.timeout) +# Global timeout exception instance - less allocations. +_timeout_exc = socket_timeout('timed out') + + def socket_connect(descriptor, address): """ Attempts to connect to the address, returns the descriptor if it succeeds, @@ -216,8 +222,7 @@ class GreenSocket(object): 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 """ @@ -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=_timeout_exc) def _recv_loop(self, recv_meth, empty_val, *args): fd = self.fd @@ -376,7 +382,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/timeout.py b/eventlet/timeout.py index f45c6d1..d109522 100644 --- a/eventlet/timeout.py +++ b/eventlet/timeout.py @@ -20,11 +20,12 @@ # 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 + from eventlet.support import greenlets as greenlet from eventlet.hubs import get_hub -__all__ = ['Timeout', - 'with_timeout'] +__all__ = ['Timeout', 'with_timeout', 'wrap_is_timeout'] _NONE = object() @@ -128,6 +129,10 @@ 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 @@ -145,3 +150,16 @@ def with_timeout(seconds, function, *args, **kwds): raise finally: timeout.cancel() + + +def wrap_is_timeout(base): + @functools.wraps(base) + def wrapped(*args, **kwargs): + ex = base(*args, **kwargs) + ex.is_timeout = True + return ex + return wrapped + + +def is_timeout(obj): + return bool(getattr(obj, 'is_timeout', None)) |
