diff --git a/src/sdam/topology_description.ts b/src/sdam/topology_description.ts index d179339b3a..5867716822 100644 --- a/src/sdam/topology_description.ts +++ b/src/sdam/topology_description.ts @@ -362,29 +362,26 @@ function topologyTypeForServerType(serverType: ServerType): TopologyType { } } +/** + * Compare objectIds. `null` is always less + * - `+1 = oid1 is greater than oid2` + * - `-1 = oid1 is less than oid2` + * - `+0 = oid1 is equal oid2` + */ function compareObjectId(oid1?: ObjectId, oid2?: ObjectId): 0 | 1 | -1 { - if (oid1 == null) { - return oid2 == null ? 0 : -1; - } - - if (oid2 == null) { - return 1; + if (oid1 == null && oid2 == null) { + return 0; } - const res = oid1.id.compare(oid2.id); - return res === 0 ? 0 : res > 0 ? 1 : -1; -} - -function compareNumber(num1?: number, num2?: number): 0 | 1 | -1 { - if (num1 == null) { - return num2 == null ? 0 : -1; + if (oid1 == null) { + return -1; } - if (num2 == null) { + if (oid2 == null) { return 1; } - return num1 === num2 ? 0 : num1 > num2 ? 1 : -1; + return oid1.id.compare(oid2.id); } function updateRsFromPrimary( @@ -403,21 +400,17 @@ function updateRsFromPrimary( const electionIdComparison = compareObjectId(maxElectionId, serverDescription.electionId); const maxElectionIdIsEqual = electionIdComparison === 0; const maxElectionIdIsLess = electionIdComparison === -1; + const maxSetVersionIsLessOrEqual = (maxSetVersion ?? -1) <= (serverDescription.setVersion ?? -1); - const setVersionComparison = compareNumber(maxSetVersion, serverDescription.setVersion); - const maxSetVersionIsLess = setVersionComparison === -1; - const maxSetVersionIsEqual = setVersionComparison === 0; - - if ( - maxElectionIdIsLess || - (maxElectionIdIsEqual && (maxSetVersionIsLess || maxSetVersionIsEqual)) - ) { - // We've seen a higher ElectionId! Update both! - // Or the electionId is the same but the setVersion increased + if (maxElectionIdIsLess || (maxElectionIdIsEqual && maxSetVersionIsLessOrEqual)) { + // The reported electionId was greater + // or the electionId was equal and reported setVersion was greater + // Always update both values, they are a tuple maxElectionId = serverDescription.electionId; maxSetVersion = serverDescription.setVersion; } else { - // this primary is stale, we must remove it + // Stale primary + // replace serverDescription with a default ServerDescription of type "Unknown" serverDescriptions.set( serverDescription.address, new ServerDescription(serverDescription.address)