Skip to content

Commit

Permalink
fix: filter servers before applying reducers
Browse files Browse the repository at this point in the history
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
  • Loading branch information
mbroadst committed May 26, 2020
1 parent f40cffc commit 99b86b3
Show file tree
Hide file tree
Showing 7 changed files with 48 additions and 51 deletions.
54 changes: 18 additions & 36 deletions lib/sdam/server_selection.js
Expand Up @@ -47,7 +47,7 @@ function maxStalenessReducer(readPreference, topologyDescription, servers) {
}

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

if (readPreference.mode === ReadPreference.PRIMARY) {
const mode = readPreference.mode;
if (mode === ReadPreference.PRIMARY) {
return servers.filter(primaryFilter);
}

if (readPreference.mode === ReadPreference.SECONDARY) {
return latencyWindowReducer(
topologyDescription,
tagSetReducer(
readPreference,
maxStalenessReducer(readPreference, topologyDescription, servers)
)
).filter(secondaryFilter);
} else if (readPreference.mode === ReadPreference.NEAREST) {
return latencyWindowReducer(
topologyDescription,
tagSetReducer(
readPreference,
maxStalenessReducer(readPreference, topologyDescription, servers)
)
).filter(nearestFilter);
} else if (readPreference.mode === ReadPreference.SECONDARY_PREFERRED) {
const result = latencyWindowReducer(
topologyDescription,
tagSetReducer(
readPreference,
maxStalenessReducer(readPreference, topologyDescription, servers)
)
).filter(secondaryFilter);

return result.length === 0 ? servers.filter(primaryFilter) : result;
} else if (readPreference.mode === ReadPreference.PRIMARY_PREFERRED) {
if (mode === ReadPreference.PRIMARY_PREFERRED) {
const result = servers.filter(primaryFilter);
if (result.length) {
return result;
}
}

const filter = mode === ReadPreference.NEAREST ? nearestFilter : secondaryFilter;
const selectedServers = latencyWindowReducer(
topologyDescription,
tagSetReducer(
readPreference,
maxStalenessReducer(readPreference, topologyDescription, servers.filter(filter))
)
);

return latencyWindowReducer(
topologyDescription,
tagSetReducer(
readPreference,
maxStalenessReducer(readPreference, topologyDescription, servers)
)
).filter(secondaryFilter);
if (mode === ReadPreference.SECONDARY_PREFERRED && selectedServers.length === 0) {
return servers.filter(primaryFilter);
}

return selectedServers;
};
}

Expand Down
3 changes: 2 additions & 1 deletion test/spec/max-staleness/Unknown/SmallMaxStaleness.json
Expand Up @@ -5,7 +5,8 @@
"servers": [
{
"address": "a:27017",
"type": "Unknown"
"type": "Unknown",
"maxWireVersion": 5
}
]
},
Expand Down
1 change: 1 addition & 0 deletions test/spec/max-staleness/Unknown/SmallMaxStaleness.yml
Expand Up @@ -7,6 +7,7 @@ topology_description:
- &1
address: a:27017
type: Unknown
maxWireVersion: 5
read_preference:
mode: Nearest
maxStalenessSeconds: 1
Expand Down
Expand Up @@ -4,7 +4,7 @@
"servers": [
{
"address": "b:27017",
"avg_rtt_ms": 5,
"avg_rtt_ms": 21,
"type": "RSSecondary",
"tags": {
"data_center": "nyc"
Expand All @@ -20,11 +20,19 @@
},
{
"address": "a:27017",
"avg_rtt_ms": 26,
"avg_rtt_ms": 37,
"type": "RSPrimary",
"tags": {
"data_center": "nyc"
}
},
{
"address": "d:27017",
"avg_rtt_ms": 5,
"type": "RSOther",
"tags": {
"data_center": "nyc"
}
}
]
},
Expand All @@ -40,15 +48,15 @@
"suitable_servers": [
{
"address": "b:27017",
"avg_rtt_ms": 5,
"avg_rtt_ms": 21,
"type": "RSSecondary",
"tags": {
"data_center": "nyc"
}
},
{
"address": "a:27017",
"avg_rtt_ms": 26,
"avg_rtt_ms": 37,
"type": "RSPrimary",
"tags": {
"data_center": "nyc"
Expand All @@ -66,7 +74,7 @@
"in_latency_window": [
{
"address": "b:27017",
"avg_rtt_ms": 5,
"avg_rtt_ms": 21,
"type": "RSSecondary",
"tags": {
"data_center": "nyc"
Expand Down
Expand Up @@ -3,7 +3,7 @@ topology_description:
servers:
- &1
address: b:27017
avg_rtt_ms: 5
avg_rtt_ms: 21
type: RSSecondary
tags:
data_center: nyc
Expand All @@ -15,10 +15,15 @@ topology_description:
data_center: nyc
- &2
address: a:27017
avg_rtt_ms: 26
avg_rtt_ms: 37
type: RSPrimary
tags:
data_center: nyc
- address: d:27017
avg_rtt_ms: 5
type: RSOther
tags:
data_center: nyc
operation: read
read_preference:
mode: Nearest
Expand Down
Expand Up @@ -4,7 +4,7 @@
"servers": [
{
"address": "b:27017",
"avg_rtt_ms": 5,
"avg_rtt_ms": 21,
"type": "RSSecondary",
"tags": {
"data_center": "nyc"
Expand All @@ -20,7 +20,7 @@
},
{
"address": "a:27017",
"avg_rtt_ms": 26,
"avg_rtt_ms": 5,
"type": "RSPrimary",
"tags": {
"data_center": "nyc"
Expand All @@ -40,7 +40,7 @@
"suitable_servers": [
{
"address": "b:27017",
"avg_rtt_ms": 5,
"avg_rtt_ms": 21,
"type": "RSSecondary",
"tags": {
"data_center": "nyc"
Expand All @@ -58,7 +58,7 @@
"in_latency_window": [
{
"address": "b:27017",
"avg_rtt_ms": 5,
"avg_rtt_ms": 21,
"type": "RSSecondary",
"tags": {
"data_center": "nyc"
Expand Down
Expand Up @@ -3,18 +3,18 @@ topology_description:
servers:
- &1
address: b:27017
avg_rtt_ms: 5
avg_rtt_ms: 21 # outside the latency window if primary is considered
type: RSSecondary
tags:
data_center: nyc
- &2
address: c:27017
avg_rtt_ms: 100
avg_rtt_ms: 100 # outside the latency window if both secondaries are considered
type: RSSecondary
tags:
data_center: nyc
- address: a:27017
avg_rtt_ms: 26
avg_rtt_ms: 5
type: RSPrimary
tags:
data_center: nyc
Expand Down

0 comments on commit 99b86b3

Please sign in to comment.