-
Notifications
You must be signed in to change notification settings - Fork 246
DRIVERS-1934: withTransaction API retries too frequently #1851
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from 12 commits
25759c4
bdcd2ef
48890a2
71ba1ba
b602606
057fbbf
42e4d94
c11aef8
a6b7b95
f40529f
56e88f0
bc9153e
5c74235
1f04505
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -41,8 +41,73 @@ If possible, drivers should implement these tests without requiring the test run | |
| the retry timeout. This might be done by internally modifying the timeout value used by `withTransaction` with some | ||
| private API or using a mock timer. | ||
|
|
||
| ### Retry Backoff is Enforced | ||
|
|
||
| Drivers should test that retries within `withTransaction` do not occur immediately. | ||
|
|
||
| 1. let `client` be a `MongoClient` | ||
| 2. let `coll` be a collection | ||
| 3. Now, run transactions without backoff: | ||
| 1. Configure the random number generator used for jitter to always return `0` -- this effectively disables backoff. | ||
|
|
||
| 2. Configure a fail point that forces 13 retries like so: | ||
|
|
||
| ```python | ||
| set_fail_point( | ||
| { | ||
| "configureFailPoint": "failCommand", | ||
| "mode": { | ||
| "times": 13 | ||
| }, # sufficiently high enough such that the time effect of backoff is noticeable | ||
| "data": { | ||
| "failCommands": ["commitTransaction"], | ||
| "errorCode": 251, | ||
| }, | ||
| } | ||
| ) | ||
| ``` | ||
|
|
||
| > [!NOTE] | ||
| > errorCode 251 is NoSuchTransaction. | ||
|
||
|
|
||
| 3. Define the callback for the transaction as follows: | ||
|
|
||
| ```python | ||
| def callback(session): | ||
| coll.insert_one({}, session=session) | ||
| ``` | ||
|
|
||
| 4. Let `no_backoff_time` be the duration of the withTransaction API call: | ||
|
|
||
| ```python | ||
| start = time.monotonic() | ||
| with client.start_session() as s: | ||
| s.with_transaction(callback) | ||
| end = time.monotonic() | ||
| no_backoff_time = end - start | ||
| ``` | ||
| 4. Now run the command with backoff: | ||
| 1. Configure the random number generator used for jitter to always return `1`. | ||
| 2. Configure a fail point that forces 13 retries like in step 3.2. | ||
| 3. Use the same callback defined in 3.3. | ||
| 4. Let `with_backoff_time` be the duration of the withTransaction API call: | ||
| ```python | ||
| start = time.monotonic() | ||
| with client.start_session() as s: | ||
| s.with_transaction(callback) | ||
| end = time.monotonic() | ||
| no_backoff_time = end - start | ||
| ``` | ||
| 5. Compare the two time between the two runs. | ||
| ```python | ||
| assertTrue(absolute_value(with_backoff_time - (no_backoff_time + 2.2 seconds)) < 1) | ||
| ``` | ||
| The sum of 13 backoffs is roughly 2.2 seconds. There is a 1-second window to account for potential variance between | ||
| the two runs. | ||
|
|
||
| ## Changelog | ||
|
|
||
| - 2025-11-18: Added Backoff test. | ||
| - 2024-09-06: Migrated from reStructuredText to Markdown. | ||
| - 2024-02-08: Converted legacy tests to unified format. | ||
| - 2021-04-29: Remove text about write concern timeouts from prose test. | ||
Uh oh!
There was an error while loading. Please reload this page.