Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit cf7a1aa

Browse files
PYTHON-5504 Prototype exponential backoff in with_transaction (#2492)
1 parent e4b7eb5 commit cf7a1aa

File tree

2 files changed

+19
-0
lines changed

2 files changed

+19
-0
lines changed

‎pymongo/asynchronous/client_session.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,9 @@
135135

136136
from __future__ import annotations
137137

138+
import asyncio
138139
import collections
140+
import random
139141
import time
140142
import uuid
141143
from collections.abc import Mapping as _Mapping
@@ -471,6 +473,8 @@ def _max_time_expired_error(exc: PyMongoError) -> bool:
471473
# This limit is non-configurable and was chosen to be twice the 60 second
472474
# default value of MongoDB's `transactionLifetimeLimitSeconds` parameter.
473475
_WITH_TRANSACTION_RETRY_TIME_LIMIT = 120
476+
_BACKOFF_MAX = 1
477+
_BACKOFF_INITIAL = 0.050 # 50ms initial backoff
474478

475479

476480
def _within_time_limit(start_time: float) -> bool:
@@ -700,7 +704,13 @@ async def callback(session, custom_arg, custom_kwarg=None):
700704
https://github.com/mongodb/specifications/blob/master/source/transactions-convenient-api/transactions-convenient-api.md#handling-errors-inside-the-callback
701705
"""
702706
start_time = time.monotonic()
707+
retry = 0
703708
while True:
709+
if retry: # Implement exponential backoff on retry.
710+
jitter = random.random() # noqa: S311
711+
backoff = jitter * min(_BACKOFF_INITIAL * (2**retry), _BACKOFF_MAX)
712+
await asyncio.sleep(backoff)
713+
retry += 1
704714
await self.start_transaction(
705715
read_concern, write_concern, read_preference, max_commit_time_ms
706716
)

‎pymongo/synchronous/client_session.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,7 @@
136136
from __future__ import annotations
137137

138138
import collections
139+
import random
139140
import time
140141
import uuid
141142
from collections.abc import Mapping as _Mapping
@@ -470,6 +471,8 @@ def _max_time_expired_error(exc: PyMongoError) -> bool:
470471
# This limit is non-configurable and was chosen to be twice the 60 second
471472
# default value of MongoDB's `transactionLifetimeLimitSeconds` parameter.
472473
_WITH_TRANSACTION_RETRY_TIME_LIMIT = 120
474+
_BACKOFF_MAX = 1
475+
_BACKOFF_INITIAL = 0.050 # 50ms initial backoff
473476

474477

475478
def _within_time_limit(start_time: float) -> bool:
@@ -699,7 +702,13 @@ def callback(session, custom_arg, custom_kwarg=None):
699702
https://github.com/mongodb/specifications/blob/master/source/transactions-convenient-api/transactions-convenient-api.md#handling-errors-inside-the-callback
700703
"""
701704
start_time = time.monotonic()
705+
retry = 0
702706
while True:
707+
if retry: # Implement exponential backoff on retry.
708+
jitter = random.random() # noqa: S311
709+
backoff = jitter * min(_BACKOFF_INITIAL * (2**retry), _BACKOFF_MAX)
710+
time.sleep(backoff)
711+
retry += 1
703712
self.start_transaction(read_concern, write_concern, read_preference, max_commit_time_ms)
704713
try:
705714
ret = callback(self)

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /