diff --git a/pymongo/lock.py b/pymongo/lock.py index b05f6acffb..9eb92f55aa 100644 --- a/pymongo/lock.py +++ b/pymongo/lock.py @@ -61,7 +61,7 @@ async def a_acquire(self, blocking: bool = True, timeout: float = -1) -> bool: return False if not blocking: return False - await asyncio.sleep(0) + await asyncio.sleep(0.001) def release(self) -> None: self._lock.release() @@ -96,7 +96,7 @@ async def acquire(self, blocking: bool = True, timeout: float = -1) -> bool: return False if not blocking: return False - await asyncio.sleep(0) + await asyncio.sleep(0.001) async def wait(self, timeout: Optional[float] = None) -> bool: if timeout is not None: diff --git a/pymongo/network_layer.py b/pymongo/network_layer.py index 82a6228acc..b772f6b109 100644 --- a/pymongo/network_layer.py +++ b/pymongo/network_layer.py @@ -114,18 +114,26 @@ def _is_ready(fut: Future) -> None: else: # The default Windows asyncio event loop does not support loop.add_reader/add_writer: # https://docs.python.org/3/library/asyncio-platforms.html#asyncio-platform-support + # Note: In PYTHON-4493 we plan to replace this code with asyncio streams. async def _async_sendall_ssl( sock: Union[socket.socket, _sslConn], buf: bytes, dummy: AbstractEventLoop ) -> None: view = memoryview(buf) total_length = len(buf) total_sent = 0 + # Backoff starts at 1ms, doubles on timeout up to 512ms, and halves on success + # down to 1ms. + backoff = 0.001 while total_sent < total_length: try: sent = sock.send(view[total_sent:]) except BLOCKING_IO_ERRORS: - await asyncio.sleep(0.5) + await asyncio.sleep(backoff) sent = 0 + if sent > 0: + backoff = max(backoff / 2, 0.001) + else: + backoff = min(backoff * 2, 0.512) total_sent += sent