Message346403
We get a ConnectionResetError exception thanks to IocpProactor.recv() callback:
def finish_recv(trans, key, ov):
try:
return ov.getresult()
except OSError as exc:
if exc.winerror in (_overlapped.ERROR_NETNAME_DELETED,
_overlapped.ERROR_OPERATION_ABORTED):
raise ConnectionResetError(*exc.args)
else:
raise
Would it be legit to convert ConnectionResetError to returning b'' in sock_recv()? Example with the test:
while True:
data = await self.loop.sock_recv(sock, DATA_SIZE)
if not data:
break
expected = bytes(islice(checker, len(data)))
self.assertEqual(data, expected)
size -= len(data)
self.assertEqual(size, 0)
"if not data:" is a common test to check if we reached the end of file or if a socket has been closed by the peer, no?
Proposed patch:
diff --git a/Lib/asyncio/proactor_events.py b/Lib/asyncio/proactor_events.py
index 9b8ae064a8..14b7f10729 100644
--- a/Lib/asyncio/proactor_events.py
+++ b/Lib/asyncio/proactor_events.py
@@ -687,10 +687,16 @@ class BaseProactorEventLoop(base_events.BaseEventLoop):
super().close()
async def sock_recv(self, sock, n):
- return await self._proactor.recv(sock, n)
+ try:
+ return await self._proactor.recv(sock, n)
+ except (ConnectionResetError, ConnectionAbortedError):
+ return b''
async def sock_recv_into(self, sock, buf):
- return await self._proactor.recv_into(sock, buf)
+ try:
+ return await self._proactor.recv_into(sock, buf)
+ except (ConnectionResetError, ConnectionAbortedError):
+ return 0
async def sock_sendall(self, sock, data):
return await self._proactor.send(sock, data)
I'm not sure about this change.
I'm not sure about sock_recv_info(): are you suppose to truncate buf to 0 bytes in this case? |
|
Date |
User |
Action |
Args |
2019-06-24 13:48:19 | vstinner | set | recipients:
+ vstinner, asvetlov, yselivanov |
2019-06-24 13:48:19 | vstinner | set | messageid: <1561384099.45.0.379173656539.issue36732@roundup.psfhosted.org> |
2019-06-24 13:48:19 | vstinner | link | issue36732 messages |
2019-06-24 13:48:19 | vstinner | create | |
|