Skip to content

Commit 4faf9f5

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 5ecf18e commit 4faf9f5

File tree

7 files changed

+48
-51
lines changed

7 files changed

+48
-51
lines changed

lib/core/sdam/server_selection.js

Lines changed: 18 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ function maxStalenessReducer(readPreference, topologyDescription, servers) {
4848
}
4949

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

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

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

236-
return latencyWindowReducer(
237-
topologyDescription,
238-
tagSetReducer(
239-
readPreference,
240-
maxStalenessReducer(readPreference, topologyDescription, servers)
241-
)
242-
).filter(secondaryFilter);
221+
if (mode === ReadPreference.SECONDARY_PREFERRED && selectedServers.length === 0) {
222+
return servers.filter(primaryFilter);
243223
}
224+
225+
return selectedServers;
244226
};
245227
}
246228

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

Lines changed: 2 additions & 1 deletion
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

Lines changed: 1 addition & 0 deletions
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

Lines changed: 13 additions & 5 deletions
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

Lines changed: 7 additions & 2 deletions
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

Lines changed: 4 additions & 4 deletions
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

Lines changed: 3 additions & 3 deletions
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)