Merge pull request #47 from methane/eintr
Retry when sock.recv() raises EINTR
This commit is contained in:
@@ -69,7 +69,7 @@ Best Practices:
|
||||
|
||||
__author__ = "Charles Gordon"
|
||||
|
||||
|
||||
import errno
|
||||
import socket
|
||||
import six
|
||||
|
||||
@@ -1056,7 +1056,7 @@ def _readline(sock, buf):
|
||||
chunks.append(buf)
|
||||
last_char = buf[-1:]
|
||||
|
||||
buf = sock.recv(RECV_SIZE)
|
||||
buf = _recv(sock, RECV_SIZE)
|
||||
if not buf:
|
||||
raise MemcacheUnexpectedCloseError()
|
||||
|
||||
@@ -1087,7 +1087,7 @@ def _readvalue(sock, buf, size):
|
||||
if buf:
|
||||
rlen -= len(buf)
|
||||
chunks.append(buf)
|
||||
buf = sock.recv(RECV_SIZE)
|
||||
buf = _recv(sock, RECV_SIZE)
|
||||
if not buf:
|
||||
raise MemcacheUnexpectedCloseError()
|
||||
|
||||
@@ -1104,3 +1104,13 @@ def _readvalue(sock, buf, size):
|
||||
chunks.append(buf[:rlen - 2])
|
||||
|
||||
return buf[rlen:], b''.join(chunks)
|
||||
|
||||
|
||||
def _recv(sock, size):
|
||||
"""sock.recv() with retry on EINTR"""
|
||||
while True:
|
||||
try:
|
||||
return sock.recv(size)
|
||||
except IOError as e:
|
||||
if e.errno != errno.EINTR:
|
||||
raise
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
# limitations under the License.
|
||||
|
||||
import collections
|
||||
import errno
|
||||
import json
|
||||
import socket
|
||||
import unittest
|
||||
@@ -627,3 +628,20 @@ class TestPrefixedPooledClient(TestPrefixedClient):
|
||||
client = PooledClient(None, serializer=serializer, key_prefix=b'xyz:')
|
||||
client.client_pool = pool.ObjectPool(lambda: mock_client)
|
||||
return client
|
||||
|
||||
|
||||
class TestRetryOnEINTR(unittest.TestCase):
|
||||
def make_client(self, values):
|
||||
client = Client(None)
|
||||
client.sock = MockSocket(list(values))
|
||||
return client
|
||||
|
||||
def test_recv(self):
|
||||
client = self.make_client([
|
||||
b'VALUE ',
|
||||
socket.error(errno.EINTR, "Interrupted system call"),
|
||||
b'key1 0 6\r\nval',
|
||||
socket.error(errno.EINTR, "Interrupted system call"),
|
||||
b'ue1\r\nEND\r\n',
|
||||
])
|
||||
tools.assert_equal(client[b'key1'], b'value1')
|
||||
|
||||
Reference in New Issue
Block a user