diff options
author | Sergey Shepelev <temotor@gmail.com> | 2017-08-25 00:37:03 +0300 |
---|---|---|
committer | Sergey Shepelev <temotor@gmail.com> | 2017-08-25 00:37:03 +0300 |
commit | 8b88cbebe5cc0463b7531b59dc255e36b9e498df (patch) | |
tree | 5d758185f46c616502ab059cb2a9fa6824725dc1 | |
parent | 3e25ba2a734642322184b997fe14c5a8d86c21b7 (diff) | |
download | eventlet-8b88cbebe5cc0463b7531b59dc255e36b9e498df.tar.gz |
greendns: early socket.timeout was breaking IO retry loopsdns-from-address-433
https://github.com/eventlet/eventlet/issues/433
-rw-r--r-- | eventlet/support/greendns.py | 43 |
1 files changed, 28 insertions, 15 deletions
diff --git a/eventlet/support/greendns.py b/eventlet/support/greendns.py index ebdea2d..cff0581 100644 --- a/eventlet/support/greendns.py +++ b/eventlet/support/greendns.py @@ -36,6 +36,7 @@ import re import struct import sys +import eventlet from eventlet import patcher from eventlet.green import _socket_nodns from eventlet.green import os @@ -617,7 +618,7 @@ def _net_read(sock, count, expiration): A Timeout exception will be raised if the operation is not completed by the expiration time. """ - s = b'' + s = bytearray() while count > 0: try: n = sock.recv(count) @@ -625,10 +626,12 @@ def _net_read(sock, count, expiration): # Q: Do we also need to catch coro.CoroutineSocketWake and pass? if expiration - time.time() <= 0.0: raise dns.exception.Timeout + eventlet.sleep(0.01) + continue if n == b'': raise EOFError count = count - len(n) - s = s + n + s += n return s @@ -698,19 +701,25 @@ def udp(q, where, timeout=DNS_QUERY_TIMEOUT, port=53, expiration = dns.query._compute_expiration(timeout) if source is not None: s.bind(source) - try: - s.sendto(wire, destination) - except socket.timeout: - # Q: Do we also need to catch coro.CoroutineSocketWake and pass? - if expiration - time.time() <= 0.0: - raise dns.exception.Timeout - while 1: + while True: + try: + s.sendto(wire, destination) + break + except socket.timeout: + # Q: Do we also need to catch coro.CoroutineSocketWake and pass? + if expiration - time.time() <= 0.0: + raise dns.exception.Timeout + eventlet.sleep(0.01) + continue + while True: try: (wire, from_address) = s.recvfrom(65535) except socket.timeout: # Q: Do we also need to catch coro.CoroutineSocketWake and pass? if expiration - time.time() <= 0.0: raise dns.exception.Timeout + eventlet.sleep(0.01) + continue if from_address == destination: break if not ignore_unexpected: @@ -771,12 +780,16 @@ def tcp(q, where, timeout=DNS_QUERY_TIMEOUT, port=53, expiration = dns.query._compute_expiration(timeout) if source is not None: s.bind(source) - try: - s.connect(destination) - except socket.timeout: - # Q: Do we also need to catch coro.CoroutineSocketWake and pass? - if expiration - time.time() <= 0.0: - raise dns.exception.Timeout + while True: + try: + s.connect(destination) + break + except socket.timeout: + # Q: Do we also need to catch coro.CoroutineSocketWake and pass? + if expiration - time.time() <= 0.0: + raise dns.exception.Timeout + eventlet.sleep(0.01) + continue l = len(wire) # copying the wire into tcpmsg is inefficient, but lets us |