Skip to content

Commit 7fa5d47

Browse files
committed
PYTHON-4636 - Avoid blocking I/O calls in async code paths
1 parent 9df635f commit 7fa5d47

File tree

2 files changed

+12
-5
lines changed

2 files changed

+12
-5
lines changed

pymongo/asynchronous/network.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -355,6 +355,7 @@ async def wait_for_read(conn: AsyncConnection, deadline: Optional[float]) -> Non
355355
"""Block until at least one byte is read, or a timeout, or a cancel."""
356356
sock = conn.conn
357357
timed_out = False
358+
timeout = _POLL_TIMEOUT
358359
# Check if the connection's socket has been manually closed
359360
if sock.fileno() == -1:
360361
return
@@ -373,16 +374,18 @@ async def wait_for_read(conn: AsyncConnection, deadline: Optional[float]) -> Non
373374
if remaining <= 0:
374375
timed_out = True
375376
timeout = max(min(remaining, _POLL_TIMEOUT), 0)
377+
if _IS_SYNC:
378+
readable = conn.socket_checker.select(sock, read=True, timeout=timeout)
376379
else:
377-
timeout = _POLL_TIMEOUT
378-
readable = conn.socket_checker.select(sock, read=True, timeout=timeout)
380+
readable = conn.socket_checker.select(sock, read=True, timeout=0.0001)
379381
if conn.cancel_context.cancelled:
380382
raise _OperationCancelled("operation cancelled")
381383
if readable:
382384
return
383385
if timed_out:
384386
raise socket.timeout("timed out")
385-
await asyncio.sleep(0)
387+
if not _IS_SYNC:
388+
await asyncio.sleep(timeout / 100.0)
386389

387390

388391
async def _receive_data_on_socket(

pymongo/synchronous/network.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -352,6 +352,7 @@ def wait_for_read(conn: Connection, deadline: Optional[float]) -> None:
352352
"""Block until at least one byte is read, or a timeout, or a cancel."""
353353
sock = conn.conn
354354
timed_out = False
355+
timeout = _POLL_TIMEOUT
355356
# Check if the connection's socket has been manually closed
356357
if sock.fileno() == -1:
357358
return
@@ -370,15 +371,18 @@ def wait_for_read(conn: Connection, deadline: Optional[float]) -> None:
370371
if remaining <= 0:
371372
timed_out = True
372373
timeout = max(min(remaining, _POLL_TIMEOUT), 0)
374+
if _IS_SYNC:
375+
readable = conn.socket_checker.select(sock, read=True, timeout=timeout)
373376
else:
374-
timeout = _POLL_TIMEOUT
375-
readable = conn.socket_checker.select(sock, read=True, timeout=timeout)
377+
readable = conn.socket_checker.select(sock, read=True, timeout=0.0001)
376378
if conn.cancel_context.cancelled:
377379
raise _OperationCancelled("operation cancelled")
378380
if readable:
379381
return
380382
if timed_out:
381383
raise socket.timeout("timed out")
384+
if not _IS_SYNC:
385+
time.sleep(timeout / 100.0)
382386

383387

384388
def _receive_data_on_socket(conn: Connection, length: int, deadline: Optional[float]) -> memoryview:

0 commit comments

Comments
 (0)