Skip to content

Commit 7ac265d

Browse files
Update for changes, test passing
1 parent 44e9771 commit 7ac265d

File tree

2 files changed

+50
-46
lines changed

2 files changed

+50
-46
lines changed

src/sessions.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -820,11 +820,11 @@ export class ClientSession
820820
}
821821

822822
if (commitError.hasErrorLabel(MongoErrorLabel.TransientTransactionError)) {
823-
const BACKOFF_INITIAL_MS = 1;
823+
const BACKOFF_INITIAL_MS = 5;
824824
const BACKOFF_MAX_MS = 500;
825825
const jitter = Math.random();
826826
const backoffMS =
827-
jitter * Math.min(BACKOFF_INITIAL_MS * 1.25 ** retry, BACKOFF_MAX_MS);
827+
jitter * Math.min(BACKOFF_INITIAL_MS * 1.5 ** retry, BACKOFF_MAX_MS);
828828

829829
if (willExceedTransactionDeadline(backoffMS)) {
830830
break;
Lines changed: 48 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,68 +1,72 @@
11
import { expect } from 'chai';
22
import { test } from 'mocha';
3+
import * as sinon from 'sinon';
34

4-
import { type CommandFailedEvent, type MongoClient } from '../../mongodb';
5-
import { configureFailPoint } from '../../tools/utils';
6-
import { filterForCommands } from '../shared';
5+
import { type MongoClient } from '../../../src';
6+
import { configureFailPoint, type FailCommandFailPoint, measureDuration } from '../../tools/utils';
77

8-
const COMMIT_FAIL_TIMES = 35;
8+
const failCommand: FailCommandFailPoint = {
9+
configureFailPoint: 'failCommand',
10+
mode: {
11+
times: 13
12+
},
13+
data: {
14+
failCommands: ['commitTransaction'],
15+
errorCode: 251
16+
}
17+
};
918

1019
describe('Retry Backoff is Enforced', function () {
11-
// Drivers should test that retries within `withTransaction` do not occur immediately. Optionally, set BACKOFF_INITIAL to a
12-
// higher value to decrease flakiness of this test. Configure a fail point that forces 30 retries. Check that the total
13-
// time for all retries exceeded 1.25 seconds.
14-
1520
let client: MongoClient;
16-
let failures: Array<CommandFailedEvent>;
1721

1822
beforeEach(async function () {
19-
client = this.configuration.newClient({}, { monitorCommands: true });
20-
21-
failures = [];
22-
client.on('commandFailed', filterForCommands('commitTransaction', failures));
23-
24-
await client.connect();
25-
26-
await configureFailPoint(this.configuration, {
27-
configureFailPoint: 'failCommand',
28-
mode: {
29-
times: COMMIT_FAIL_TIMES
30-
},
31-
data: {
32-
failCommands: ['commitTransaction'],
33-
errorCode: 24
34-
}
35-
});
23+
client = this.configuration.newClient();
3624
});
3725

3826
afterEach(async function () {
27+
sinon.restore();
3928
await client?.close();
4029
});
4130

42-
for (let i = 0; i < 250; ++i) {
43-
test.only(
44-
'works' + i,
45-
{
46-
requires: {
47-
mongodb: '>=4.4', // failCommand
48-
topology: '!single' // transactions can't run on standalone servers
49-
}
50-
},
51-
async function () {
52-
const start = performance.now();
31+
test(
32+
'works',
33+
{
34+
requires: {
35+
mongodb: '>=4.4', // failCommand
36+
topology: '!single' // transactions can't run on standalone servers
37+
}
38+
},
39+
async function () {
40+
const randomStub = sinon.stub(Math, 'random');
41+
42+
randomStub.returns(0);
5343

54-
await client.withSession(async s => {
44+
await configureFailPoint(this.configuration, failCommand);
45+
46+
const { duration: noBackoffTime } = await measureDuration(() => {
47+
return client.withSession(async s => {
5548
await s.withTransaction(async s => {
5649
await client.db('foo').collection('bar').insertOne({ name: 'bailey' }, { session: s });
5750
});
5851
});
52+
});
5953

60-
const end = performance.now();
54+
randomStub.returns(1);
6155

62-
expect(failures).to.have.lengthOf(COMMIT_FAIL_TIMES);
56+
await configureFailPoint(this.configuration, failCommand);
6357

64-
expect(end - start).to.be.greaterThan(1250);
65-
}
66-
);
67-
}
58+
const { duration: fullBackoffDuration } = await measureDuration(() => {
59+
return client.withSession(async s => {
60+
await s.withTransaction(async s => {
61+
await client.db('foo').collection('bar').insertOne({ name: 'bailey' }, { session: s });
62+
});
63+
});
64+
});
65+
66+
expect(fullBackoffDuration).to.be.within(
67+
noBackoffTime + 2200 - 1000,
68+
noBackoffTime + 2200 + 1000
69+
);
70+
}
71+
);
6872
});

0 commit comments

Comments
 (0)