Skip to content

Commit 1125200

Browse files
NoahStappbaileympearsonblink1073papafetadjik1
authored
DRIVERS-3239, DRIVERS-3411, DRIVERS-3370, DRIVERS-3412: Client backpressure (mongodb#1907)
Co-authored-by: Bailey Pearson <bailey.pearson@mongodb.com> Co-authored-by: Steven Silvester <steve.silvester@mongodb.com> Co-authored-by: Ferdinando Papale <4850119+papafe@users.noreply.github.com> Co-authored-by: Sergey Zelenov <mail@zelenov.su> Co-authored-by: Isabel Atkinson <isabel.atkinson@mongodb.com>
1 parent 9e639cc commit 1125200

31 files changed

+13190
-26
lines changed

source/client-backpressure/client-backpressure.md

Lines changed: 467 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
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 a number as close as possible to `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` with `adaptiveRetries=True`.
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`.
71+
72+
#### Test 3: Overload Errors are Retried a Maximum of MAX_RETRIES times
73+
74+
Drivers should test that without adaptive retries enabled, overload errors are retried a maximum of five times.
75+
76+
1. Let `client` be a `MongoClient` with command event monitoring enabled.
77+
78+
2. Let `coll` be a collection.
79+
80+
3. Configure the following failpoint:
81+
82+
```javascript
83+
{
84+
configureFailPoint: 'failCommand',
85+
mode: 'alwaysOn',
86+
data: {
87+
failCommands: ['find'],
88+
errorCode: 462, // IngressRequestRateLimitExceeded
89+
errorLabels: ['SystemOverloadedError', 'RetryableError']
90+
}
91+
}
92+
```
93+
94+
4. Perform a find operation with `coll` that fails.
95+
96+
5. Assert that the raised error contains both the `RetryableError` and `SystemOverloadedError` error labels.
97+
98+
6. Assert that the total number of started commands is MAX_RETRIES + 1 (6).
99+
100+
#### Test 4: Adaptive Retries are Limited by Token Bucket Tokens
101+
102+
Drivers should test that when enabled, adaptive retries are limited by the number of tokens in the bucket.
103+
104+
1. Let `client` be a `MongoClient` with `adaptiveRetries=True` and command event monitoring enabled.
105+
106+
2. Set `client`'s retry token bucket to have 2 tokens.
107+
108+
3. Let `coll` be a collection.
109+
110+
4. Configure the following failpoint:
111+
112+
```javascript
113+
{
114+
configureFailPoint: 'failCommand',
115+
mode: {times: 3},
116+
data: {
117+
failCommands: ['find'],
118+
errorCode: 462, // IngressRequestRateLimitExceeded
119+
errorLabels: ['SystemOverloadedError', 'RetryableError']
120+
}
121+
}
122+
```
123+
124+
5. Perform a find operation with `coll` that fails.
125+
126+
6. Assert that the raised error contains both the `RetryableError` and `SystemOverloadedError` error labels.
127+
128+
7. Assert that the total number of started commands is 3: one for the initial attempt and two for the retries.

0 commit comments

Comments
 (0)