PYTHON-3290 Nested pymongo.timeout() calls only shorten the deadline (#966)

This commit is contained in:
Shane Harvey 2022-06-07 17:40:46 -04:00 committed by GitHub
parent 77ace9a988
commit a6ae852c36
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 9 additions and 7 deletions

View File

@ -127,8 +127,9 @@ def timeout(seconds: Optional[float]) -> ContextManager:
NetworkTimeout) as exc:
print(f"block timed out: {exc!r}")
When nesting :func:`~pymongo.timeout`, the nested block overrides the
timeout. When exiting the block, the previous deadline is restored::
When nesting :func:`~pymongo.timeout`, the newly computed deadline is capped to at most
the existing deadline. The deadline can only be shortened, not extended.
When exiting the block, the previous deadline is restored::
with pymongo.timeout(5):
coll.find_one() # Uses the 5 second deadline.
@ -136,7 +137,7 @@ def timeout(seconds: Optional[float]) -> ContextManager:
coll.find_one() # Uses the 3 second deadline.
coll.find_one() # Uses the original 5 second deadline.
with pymongo.timeout(10):
coll.find_one() # Uses the 10 second deadline.
coll.find_one() # Still uses the original 5 second deadline.
coll.find_one() # Uses the original 5 second deadline.
:Parameters:

View File

@ -70,9 +70,9 @@ class _TimeoutContext(object):
def __enter__(self):
timeout_token = TIMEOUT.set(self._timeout)
deadline_token = DEADLINE.set(
time.monotonic() + self._timeout if self._timeout else float("inf")
)
prev_deadline = DEADLINE.get()
next_deadline = time.monotonic() + self._timeout if self._timeout else float("inf")
deadline_token = DEADLINE.set(min(prev_deadline, next_deadline))
rtt_token = RTT.set(0.0)
self._tokens = (timeout_token, deadline_token, rtt_token)
return self

View File

@ -43,10 +43,11 @@ class TestCSOT(IntegrationTest):
self.assertEqual(_csot.get_timeout(), 10)
deadline_10 = _csot.get_deadline()
# Capped at the original 10 deadline.
with pymongo.timeout(15):
coll.find_one()
self.assertEqual(_csot.get_timeout(), 15)
self.assertGreater(_csot.get_deadline(), deadline_10)
self.assertEqual(_csot.get_deadline(), deadline_10)
# Should be reset to previous values
self.assertEqual(_csot.get_timeout(), 10)