Skip to content

Commit 7ef1b81

Browse files
baileympearsonblink1073papafeNoahStapp
authored
DRIVERS-3239: Add exponential backoff to operation retry loop for server overloaded errors (#1862)
Co-authored-by: Steven Silvester <steve.silvester@mongodb.com> Co-authored-by: Ferdinando Papale <4850119+papafe@users.noreply.github.com> Co-authored-by: Noah Stapp <noah.stapp@mongodb.com>
1 parent bb9dddd commit 7ef1b81

26 files changed

+13010
-22
lines changed

source/client-backpressure/client-backpressure.md

Lines changed: 452 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
# Client Backpressure Tests
2+
3+
______________________________________________________________________
4+
5+
## Introduction
6+
7+
The YAML and JSON files in this directory are platform-independent tests meant to exercise a driver's implementation of
8+
retryable reads. These tests utilize the [Unified Test Format](../../unified-test-format/unified-test-format.md).
9+
10+
Several prose tests, which are not easily expressed in YAML, are also presented in this file. Those tests will need to
11+
be manually implemented by each driver.
12+
13+
### Prose Tests
14+
15+
#### Test 1: Operation Retry Uses Exponential Backoff
16+
17+
Drivers should test that retries do not occur immediately when a SystemOverloadedError is encountered.
18+
19+
1. Let `client` be a `MongoClient`
20+
2. Let `collection` be a collection
21+
3. Now, run transactions without backoff:
22+
1. Configure the random number generator used for jitter to always return `0` -- this effectively disables backoff.
23+
24+
2. Configure the following failPoint:
25+
26+
```javascript
27+
{
28+
configureFailPoint: 'failCommand',
29+
mode: 'alwaysOn',
30+
data: {
31+
failCommands: ['insert'],
32+
errorCode: 2,
33+
errorLabels: ['SystemOverloadedError', 'RetryableError']
34+
}
35+
}
36+
```
37+
38+
3. Insert the document `{ a: 1 }`. Expect that the command errors. Measure the duration of the command execution.
39+
40+
```javascript
41+
const start = performance.now();
42+
expect(
43+
await coll.insertOne({ a: 1 }).catch(e => e)
44+
).to.be.an.instanceof(MongoServerError);
45+
const end = performance.now();
46+
```
47+
48+
4. Configure the random number generator used for jitter to always return `1`.
49+
50+
5. Execute step 3 again.
51+
52+
6. Compare the two time between the two runs.
53+
54+
```python
55+
assertTrue(with_backoff_time - no_backoff_time >= 2.1)
56+
```
57+
58+
The sum of 5 backoffs is 3.1 seconds. There is a 1-second window to account for potential variance between the two
59+
runs.
60+
61+
#### Test 2: Token Bucket Capacity is Enforced
62+
63+
Drivers should test that retry token buckets are created at their maximum capacity and that that capacity is enforced.
64+
65+
1. Let `client` be a `MongoClient`.
66+
2. Assert that the client's retry token bucket is at full capacity and that the capacity is
67+
`DEFAULT_RETRY_TOKEN_CAPACITY`.
68+
3. Using `client`, execute a successful `ping` command.
69+
4. Assert that the successful command did not increase the number of tokens in the bucket above
70+
`DEFAULT_RETRY_TOKEN_CAPACITY`.

0 commit comments

Comments
 (0)