Skip to content

Commit 99b86b3

Browse files
committed
fix: filter servers before applying reducers
In order to accurately reduce the set of viable servers for server selection, we need to filter the set by the read preference BEFORE we reduce by max staleness, tagSet and latency window. NODE-2407
1 parent f40cffc commit 99b86b3

File tree

7 files changed

+48
-51
lines changed

7 files changed

+48
-51
lines changed

lib/sdam/server_selection.js

+18-36
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ function maxStalenessReducer(readPreference, topologyDescription, servers) {
4747
}
4848

4949
if (topologyDescription.type === TopologyType.ReplicaSetWithPrimary) {
50-
const primary = servers.filter(primaryFilter)[0];
50+
const primary = Array.from(topologyDescription.servers.values()).filter(primaryFilter)[0];
5151
return servers.reduce((result, server) => {
5252
const stalenessMS =
5353
server.lastUpdateTime -
@@ -196,50 +196,32 @@ function readPreferenceServerSelector(readPreference) {
196196
return latencyWindowReducer(topologyDescription, servers.filter(knownFilter));
197197
}
198198

199-
if (readPreference.mode === ReadPreference.PRIMARY) {
199+
const mode = readPreference.mode;
200+
if (mode === ReadPreference.PRIMARY) {
200201
return servers.filter(primaryFilter);
201202
}
202203

203-
if (readPreference.mode === ReadPreference.SECONDARY) {
204-
return latencyWindowReducer(
205-
topologyDescription,
206-
tagSetReducer(
207-
readPreference,
208-
maxStalenessReducer(readPreference, topologyDescription, servers)
209-
)
210-
).filter(secondaryFilter);
211-
} else if (readPreference.mode === ReadPreference.NEAREST) {
212-
return latencyWindowReducer(
213-
topologyDescription,
214-
tagSetReducer(
215-
readPreference,
216-
maxStalenessReducer(readPreference, topologyDescription, servers)
217-
)
218-
).filter(nearestFilter);
219-
} else if (readPreference.mode === ReadPreference.SECONDARY_PREFERRED) {
220-
const result = latencyWindowReducer(
221-
topologyDescription,
222-
tagSetReducer(
223-
readPreference,
224-
maxStalenessReducer(readPreference, topologyDescription, servers)
225-
)
226-
).filter(secondaryFilter);
227-
228-
return result.length === 0 ? servers.filter(primaryFilter) : result;
229-
} else if (readPreference.mode === ReadPreference.PRIMARY_PREFERRED) {
204+
if (mode === ReadPreference.PRIMARY_PREFERRED) {
230205
const result = servers.filter(primaryFilter);
231206
if (result.length) {
232207
return result;
233208
}
209+
}
210+
211+
const filter = mode === ReadPreference.NEAREST ? nearestFilter : secondaryFilter;
212+
const selectedServers = latencyWindowReducer(
213+
topologyDescription,
214+
tagSetReducer(
215+
readPreference,
216+
maxStalenessReducer(readPreference, topologyDescription, servers.filter(filter))
217+
)
218+
);
234219

235-
return latencyWindowReducer(
236-
topologyDescription,
237-
tagSetReducer(
238-
readPreference,
239-
maxStalenessReducer(readPreference, topologyDescription, servers)
240-
)
241-
).filter(secondaryFilter);
220+
if (mode === ReadPreference.SECONDARY_PREFERRED && selectedServers.length === 0) {
221+
return servers.filter(primaryFilter);
242222
}
223+
224+
return selectedServers;
243225
};
244226
}
245227

test/spec/max-staleness/Unknown/SmallMaxStaleness.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@
55
"servers": [
66
{
77
"address": "a:27017",
8-
"type": "Unknown"
8+
"type": "Unknown",
9+
"maxWireVersion": 5
910
}
1011
]
1112
},

test/spec/max-staleness/Unknown/SmallMaxStaleness.yml

+1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ topology_description:
77
- &1
88
address: a:27017
99
type: Unknown
10+
maxWireVersion: 5
1011
read_preference:
1112
mode: Nearest
1213
maxStalenessSeconds: 1

test/spec/server-selection/server_selection/ReplicaSetWithPrimary/read/Nearest.json

+13-5
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
"servers": [
55
{
66
"address": "b:27017",
7-
"avg_rtt_ms": 5,
7+
"avg_rtt_ms": 21,
88
"type": "RSSecondary",
99
"tags": {
1010
"data_center": "nyc"
@@ -20,11 +20,19 @@
2020
},
2121
{
2222
"address": "a:27017",
23-
"avg_rtt_ms": 26,
23+
"avg_rtt_ms": 37,
2424
"type": "RSPrimary",
2525
"tags": {
2626
"data_center": "nyc"
2727
}
28+
},
29+
{
30+
"address": "d:27017",
31+
"avg_rtt_ms": 5,
32+
"type": "RSOther",
33+
"tags": {
34+
"data_center": "nyc"
35+
}
2836
}
2937
]
3038
},
@@ -40,15 +48,15 @@
4048
"suitable_servers": [
4149
{
4250
"address": "b:27017",
43-
"avg_rtt_ms": 5,
51+
"avg_rtt_ms": 21,
4452
"type": "RSSecondary",
4553
"tags": {
4654
"data_center": "nyc"
4755
}
4856
},
4957
{
5058
"address": "a:27017",
51-
"avg_rtt_ms": 26,
59+
"avg_rtt_ms": 37,
5260
"type": "RSPrimary",
5361
"tags": {
5462
"data_center": "nyc"
@@ -66,7 +74,7 @@
6674
"in_latency_window": [
6775
{
6876
"address": "b:27017",
69-
"avg_rtt_ms": 5,
77+
"avg_rtt_ms": 21,
7078
"type": "RSSecondary",
7179
"tags": {
7280
"data_center": "nyc"

test/spec/server-selection/server_selection/ReplicaSetWithPrimary/read/Nearest.yml

+7-2
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ topology_description:
33
servers:
44
- &1
55
address: b:27017
6-
avg_rtt_ms: 5
6+
avg_rtt_ms: 21
77
type: RSSecondary
88
tags:
99
data_center: nyc
@@ -15,10 +15,15 @@ topology_description:
1515
data_center: nyc
1616
- &2
1717
address: a:27017
18-
avg_rtt_ms: 26
18+
avg_rtt_ms: 37
1919
type: RSPrimary
2020
tags:
2121
data_center: nyc
22+
- address: d:27017
23+
avg_rtt_ms: 5
24+
type: RSOther
25+
tags:
26+
data_center: nyc
2227
operation: read
2328
read_preference:
2429
mode: Nearest

test/spec/server-selection/server_selection/ReplicaSetWithPrimary/read/Secondary.json

+4-4
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
"servers": [
55
{
66
"address": "b:27017",
7-
"avg_rtt_ms": 5,
7+
"avg_rtt_ms": 21,
88
"type": "RSSecondary",
99
"tags": {
1010
"data_center": "nyc"
@@ -20,7 +20,7 @@
2020
},
2121
{
2222
"address": "a:27017",
23-
"avg_rtt_ms": 26,
23+
"avg_rtt_ms": 5,
2424
"type": "RSPrimary",
2525
"tags": {
2626
"data_center": "nyc"
@@ -40,7 +40,7 @@
4040
"suitable_servers": [
4141
{
4242
"address": "b:27017",
43-
"avg_rtt_ms": 5,
43+
"avg_rtt_ms": 21,
4444
"type": "RSSecondary",
4545
"tags": {
4646
"data_center": "nyc"
@@ -58,7 +58,7 @@
5858
"in_latency_window": [
5959
{
6060
"address": "b:27017",
61-
"avg_rtt_ms": 5,
61+
"avg_rtt_ms": 21,
6262
"type": "RSSecondary",
6363
"tags": {
6464
"data_center": "nyc"

test/spec/server-selection/server_selection/ReplicaSetWithPrimary/read/Secondary.yml

+3-3
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,18 @@ topology_description:
33
servers:
44
- &1
55
address: b:27017
6-
avg_rtt_ms: 5
6+
avg_rtt_ms: 21 # outside the latency window if primary is considered
77
type: RSSecondary
88
tags:
99
data_center: nyc
1010
- &2
1111
address: c:27017
12-
avg_rtt_ms: 100
12+
avg_rtt_ms: 100 # outside the latency window if both secondaries are considered
1313
type: RSSecondary
1414
tags:
1515
data_center: nyc
1616
- address: a:27017
17-
avg_rtt_ms: 26
17+
avg_rtt_ms: 5
1818
type: RSPrimary
1919
tags:
2020
data_center: nyc

0 commit comments

Comments
 (0)