Skip to content

Commit f1c5c3c

Browse files
refactor(NODE-4690): update cmap and test runners to support interruptInUseConnections (mongodb#3443)
1 parent 6fb87e4 commit f1c5c3c

17 files changed

+1383
-8
lines changed

src/cmap/connection_pool.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -428,7 +428,7 @@ export class ConnectionPool extends TypedEventEmitter<ConnectionPoolEvents> {
428428
}
429429
this.emit(
430430
ConnectionPool.CONNECTION_POOL_CLEARED,
431-
new ConnectionPoolClearedEvent(this, serviceId)
431+
new ConnectionPoolClearedEvent(this, { serviceId })
432432
);
433433
return;
434434
}

src/cmap/connection_pool_events.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -187,9 +187,15 @@ export class ConnectionPoolClearedEvent extends ConnectionPoolMonitoringEvent {
187187
/** @internal */
188188
serviceId?: ObjectId;
189189

190+
interruptInUseConnections?: boolean;
191+
190192
/** @internal */
191-
constructor(pool: ConnectionPool, serviceId?: ObjectId) {
193+
constructor(
194+
pool: ConnectionPool,
195+
options: { serviceId?: ObjectId; interruptInUseConnections?: boolean } = {}
196+
) {
192197
super(pool);
193-
this.serviceId = serviceId;
198+
this.serviceId = options.serviceId;
199+
this.interruptInUseConnections = options.interruptInUseConnections;
194200
}
195201
}

test/integration/connection-monitoring-and-pooling/connection_monitoring_and_pooling.spec.test.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,16 @@ const LB_SKIP_TESTS: SkipDescription[] = [
1919
skipReason: 'cannot run against a load balanced environment'
2020
}));
2121

22+
const INTERRUPT_IN_USE_CONNECTIONS_TESTS: SkipDescription[] = [
23+
'Connections MUST be interrupted as soon as possible (interruptInUseConnections=true)',
24+
'Pool clear SHOULD schedule the next background thread run immediately (interruptInUseConnections: false)',
25+
'clear with interruptInUseConnections = true closes pending connections'
26+
].map(description => ({
27+
description,
28+
skipIfCondition: 'always',
29+
skipReason: 'TODO(NODE-4691): cancel inflight operations when heartbeat fails'
30+
}));
31+
2232
describe('Connection Monitoring and Pooling Spec Tests (Integration)', function () {
2333
const tests: CmapTest[] = loadSpecTests('connection-monitoring-and-pooling');
2434

@@ -30,6 +40,6 @@ describe('Connection Monitoring and Pooling Spec Tests (Integration)', function
3040
skipReason:
3141
'not applicable: waitQueueTimeoutMS limits connection establishment time in our driver'
3242
}
33-
])
43+
]).concat(INTERRUPT_IN_USE_CONNECTIONS_TESTS)
3444
});
3545
});

test/integration/server-discovery-and-monitoring/server_discovery_and_monitoring.spec.test.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,16 @@ import { loadSpecTests } from '../../spec';
44
import { runUnifiedSuite } from '../../tools/unified-spec-runner/runner';
55

66
describe('SDAM Unified Tests', function () {
7-
runUnifiedSuite(loadSpecTests(path.join('server-discovery-and-monitoring', 'unified')));
7+
const sdamPoolClearedTests = [
8+
'Connection pool clear uses interruptInUseConnections=true after monitor timeout',
9+
'Error returned from connection pool clear with interruptInUseConnections=true is retryable',
10+
'Error returned from connection pool clear with interruptInUseConnections=true is retryable for write'
11+
];
12+
runUnifiedSuite(
13+
loadSpecTests(path.join('server-discovery-and-monitoring', 'unified')),
14+
({ description }) =>
15+
sdamPoolClearedTests.includes(description)
16+
? 'TODO(NODE-4691): interrupt in-use operations on heartbeat failure'
17+
: false
18+
);
819
});
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
{
2+
"version": 1,
3+
"style": "unit",
4+
"description": "Connections MUST be interrupted as soon as possible (interruptInUseConnections=true)",
5+
"poolOptions": {
6+
"backgroundThreadIntervalMS": 10000
7+
},
8+
"operations": [
9+
{
10+
"name": "ready"
11+
},
12+
{
13+
"name": "checkOut"
14+
},
15+
{
16+
"name": "checkOut",
17+
"label": "conn"
18+
},
19+
{
20+
"name": "clear",
21+
"interruptInUseConnections": true
22+
},
23+
{
24+
"name": "waitForEvent",
25+
"event": "ConnectionPoolCleared",
26+
"count": 1,
27+
"timeout": 1000
28+
},
29+
{
30+
"name": "waitForEvent",
31+
"event": "ConnectionClosed",
32+
"count": 2,
33+
"timeout": 1000
34+
},
35+
{
36+
"name": "close"
37+
}
38+
],
39+
"events": [
40+
{
41+
"type": "ConnectionCheckedOut",
42+
"connectionId": 1,
43+
"address": 42
44+
},
45+
{
46+
"type": "ConnectionCheckedOut",
47+
"connectionId": 2,
48+
"address": 42
49+
},
50+
{
51+
"type": "ConnectionPoolCleared",
52+
"interruptInUseConnections": true
53+
},
54+
{
55+
"type": "ConnectionClosed",
56+
"reason": "stale",
57+
"address": 42
58+
},
59+
{
60+
"type": "ConnectionClosed",
61+
"reason": "stale",
62+
"address": 42
63+
},
64+
{
65+
"type": "ConnectionPoolClosed",
66+
"address": 42
67+
}
68+
],
69+
"ignore": [
70+
"ConnectionCreated",
71+
"ConnectionPoolReady",
72+
"ConnectionReady",
73+
"ConnectionCheckOutStarted",
74+
"ConnectionPoolCreated",
75+
"ConnectionCheckedIn"
76+
]
77+
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
version: 1
2+
style: unit
3+
description: Connections MUST be interrupted as soon as possible (interruptInUseConnections=true)
4+
poolOptions:
5+
# ensure it's not involved by default
6+
backgroundThreadIntervalMS: 10000
7+
operations:
8+
- name: ready
9+
- name: checkOut
10+
- name: checkOut
11+
label: conn
12+
- name: clear
13+
interruptInUseConnections: true
14+
- name: waitForEvent
15+
event: ConnectionPoolCleared
16+
count: 1
17+
timeout: 1000
18+
- name: waitForEvent
19+
event: ConnectionClosed
20+
count: 2
21+
timeout: 1000
22+
- name: close
23+
events:
24+
- type: ConnectionCheckedOut
25+
connectionId: 1
26+
address: 42
27+
- type: ConnectionCheckedOut
28+
connectionId: 2
29+
address: 42
30+
- type: ConnectionPoolCleared
31+
interruptInUseConnections: true
32+
- type: ConnectionClosed
33+
reason: stale
34+
address: 42
35+
- type: ConnectionClosed
36+
reason: stale
37+
address: 42
38+
- type: ConnectionPoolClosed
39+
address: 42
40+
ignore:
41+
- ConnectionCreated
42+
- ConnectionPoolReady
43+
- ConnectionReady
44+
- ConnectionCheckOutStarted
45+
- ConnectionPoolCreated
46+
- ConnectionCheckedIn
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
{
2+
"version": 1,
3+
"style": "integration",
4+
"description": "clear with interruptInUseConnections = true closes pending connections",
5+
"runOn": [
6+
{
7+
"minServerVersion": "4.9.0"
8+
}
9+
],
10+
"failPoint": {
11+
"configureFailPoint": "failCommand",
12+
"mode": "alwaysOn",
13+
"data": {
14+
"failCommands": [
15+
"isMaster",
16+
"hello"
17+
],
18+
"closeConnection": false,
19+
"blockConnection": true,
20+
"blockTimeMS": 1000
21+
}
22+
},
23+
"poolOptions": {
24+
"minPoolSize": 0
25+
},
26+
"operations": [
27+
{
28+
"name": "ready"
29+
},
30+
{
31+
"name": "start",
32+
"target": "thread1"
33+
},
34+
{
35+
"name": "checkOut",
36+
"thread": "thread1"
37+
},
38+
{
39+
"name": "waitForEvent",
40+
"event": "ConnectionCreated",
41+
"count": 1
42+
},
43+
{
44+
"name": "clear",
45+
"interruptInUseConnections": true
46+
},
47+
{
48+
"name": "waitForEvent",
49+
"event": "ConnectionCheckOutFailed",
50+
"count": 1
51+
}
52+
],
53+
"events": [
54+
{
55+
"type": "ConnectionCheckOutStarted"
56+
},
57+
{
58+
"type": "ConnectionCreated"
59+
},
60+
{
61+
"type": "ConnectionPoolCleared",
62+
"interruptInUseConnections": true
63+
},
64+
{
65+
"type": "ConnectionClosed"
66+
},
67+
{
68+
"type": "ConnectionCheckOutFailed"
69+
}
70+
],
71+
"ignore": [
72+
"ConnectionCheckedIn",
73+
"ConnectionCheckedOut",
74+
"ConnectionPoolCreated",
75+
"ConnectionPoolReady"
76+
]
77+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
version: 1
2+
style: integration
3+
description: clear with interruptInUseConnections = true closes pending connections
4+
runOn:
5+
-
6+
minServerVersion: "4.9.0"
7+
failPoint:
8+
configureFailPoint: failCommand
9+
mode: "alwaysOn"
10+
data:
11+
failCommands: ["isMaster","hello"]
12+
closeConnection: false
13+
blockConnection: true
14+
blockTimeMS: 1000
15+
poolOptions:
16+
minPoolSize: 0
17+
operations:
18+
- name: ready
19+
- name: start
20+
target: thread1
21+
- name: checkOut
22+
thread: thread1
23+
- name: waitForEvent
24+
event: ConnectionCreated
25+
count: 1
26+
- name: clear
27+
interruptInUseConnections: true
28+
- name: waitForEvent
29+
event: ConnectionCheckOutFailed
30+
count: 1
31+
events:
32+
- type: ConnectionCheckOutStarted
33+
- type: ConnectionCreated
34+
- type: ConnectionPoolCleared
35+
interruptInUseConnections: true
36+
- type: ConnectionClosed
37+
- type: ConnectionCheckOutFailed
38+
ignore:
39+
- ConnectionCheckedIn
40+
- ConnectionCheckedOut
41+
- ConnectionPoolCreated
42+
- ConnectionPoolReady
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
{
2+
"version": 1,
3+
"style": "unit",
4+
"description": "Pool clear SHOULD schedule the next background thread run immediately (interruptInUseConnections: false)",
5+
"poolOptions": {
6+
"backgroundThreadIntervalMS": 10000
7+
},
8+
"operations": [
9+
{
10+
"name": "ready"
11+
},
12+
{
13+
"name": "checkOut"
14+
},
15+
{
16+
"name": "checkOut",
17+
"label": "conn"
18+
},
19+
{
20+
"name": "checkIn",
21+
"connection": "conn"
22+
},
23+
{
24+
"name": "clear",
25+
"interruptInUseConnections": false
26+
},
27+
{
28+
"name": "waitForEvent",
29+
"event": "ConnectionPoolCleared",
30+
"count": 1,
31+
"timeout": 1000
32+
},
33+
{
34+
"name": "waitForEvent",
35+
"event": "ConnectionClosed",
36+
"count": 1,
37+
"timeout": 1000
38+
},
39+
{
40+
"name": "close"
41+
}
42+
],
43+
"events": [
44+
{
45+
"type": "ConnectionCheckedOut",
46+
"connectionId": 1,
47+
"address": 42
48+
},
49+
{
50+
"type": "ConnectionCheckedOut",
51+
"connectionId": 2,
52+
"address": 42
53+
},
54+
{
55+
"type": "ConnectionCheckedIn",
56+
"connectionId": 2,
57+
"address": 42
58+
},
59+
{
60+
"type": "ConnectionPoolCleared",
61+
"interruptInUseConnections": false
62+
},
63+
{
64+
"type": "ConnectionClosed",
65+
"connectionId": 2,
66+
"reason": "stale",
67+
"address": 42
68+
},
69+
{
70+
"type": "ConnectionPoolClosed",
71+
"address": 42
72+
}
73+
],
74+
"ignore": [
75+
"ConnectionCreated",
76+
"ConnectionPoolReady",
77+
"ConnectionReady",
78+
"ConnectionCheckOutStarted",
79+
"ConnectionPoolCreated"
80+
]
81+
}

0 commit comments

Comments
 (0)