@@ -130,7 +130,7 @@ def _is_ready(fut: Future) -> None:
130
130
loop .remove_writer (fd )
131
131
132
132
async def _async_receive_ssl (
133
- conn : _sslConn , length : int , loop : AbstractEventLoop
133
+ conn : _sslConn , length : int , loop : AbstractEventLoop , once : Optional [ bool ] = False
134
134
) -> memoryview :
135
135
mv = memoryview (bytearray (length ))
136
136
total_read = 0
@@ -145,6 +145,8 @@ def _is_ready(fut: Future) -> None:
145
145
read = conn .recv_into (mv [total_read :])
146
146
if read == 0 :
147
147
raise OSError ("connection closed" )
148
+ if once :
149
+ return mv [:read ]
148
150
total_read += read
149
151
except BLOCKING_IO_ERRORS as exc :
150
152
fd = conn .fileno ()
@@ -275,36 +277,21 @@ async def async_receive_data(
275
277
sock .settimeout (sock_timeout )
276
278
277
279
278
- async def _async_receive_data_socket (
279
- sock : socket .socket | _sslConn , length : int , deadline : Optional [float ]
280
- ) -> memoryview :
280
+ async def _async_receive_data_socket (sock : socket .socket | _sslConn , length : int ) -> memoryview :
281
281
sock_timeout = sock .gettimeout ()
282
- timeout : Optional [Union [float , int ]]
283
- if deadline :
284
- # When the timeout has expired perform one final check to
285
- # see if the socket is readable. This helps avoid spurious
286
- # timeouts on AWS Lambda and other FaaS environments.
287
- timeout = max (deadline - time .monotonic (), 0 )
288
- else :
289
- timeout = sock_timeout
282
+ timeout = sock_timeout
290
283
291
284
sock .settimeout (0.0 )
292
285
loop = asyncio .get_event_loop ()
293
286
try :
294
287
if _HAVE_SSL and isinstance (sock , (SSLSocket , _sslConn )):
295
- read_task = asyncio .create_task (_async_receive_ssl (sock , length , loop )) # type: ignore[arg-type]
288
+ return await asyncio .wait_for (
289
+ _async_receive_ssl (sock , length , loop , once = True ), timeout = timeout
290
+ ) # type: ignore[arg-type]
296
291
else :
297
- read_task = asyncio .create_task (_async_receive (sock , length , loop )) # type: ignore[arg-type]
298
- tasks = [read_task ]
299
- done , pending = await asyncio .wait (
300
- tasks , timeout = timeout , return_when = asyncio .FIRST_COMPLETED
301
- )
302
- for task in pending :
303
- task .cancel ()
304
- await asyncio .wait (pending )
305
- if read_task in done :
306
- return read_task .result ()
307
- raise socket .timeout ("timed out" )
292
+ return await asyncio .wait_for (_async_receive (sock , length , loop ), timeout = timeout ) # type: ignore[arg-type]
293
+ except asyncio .TimeoutError as err :
294
+ raise socket .timeout ("timed out" ) from err
308
295
finally :
309
296
sock .settimeout (sock_timeout )
310
297
0 commit comments