|
1 | 1 | import { Document, Long, ObjectId } from '../bson'; |
2 | 2 | import type { MongoError } from '../error'; |
3 | | -import { arrayStrictEqual, errorStrictEqual, HostAddress, now } from '../utils'; |
| 3 | +import { arrayStrictEqual, compareObjectId, errorStrictEqual, HostAddress, now } from '../utils'; |
4 | 4 | import type { ClusterTime } from './common'; |
5 | 5 | import { ServerType } from './common'; |
6 | 6 |
|
@@ -105,6 +105,7 @@ export class ServerDescription { |
105 | 105 | if (options?.topologyVersion) { |
106 | 106 | this.topologyVersion = options.topologyVersion; |
107 | 107 | } else if (hello?.topologyVersion) { |
| 108 | + // TODO(NODE-2674): Preserve int64 sent from MongoDB |
108 | 109 | this.topologyVersion = hello.topologyVersion; |
109 | 110 | } |
110 | 111 |
|
@@ -179,15 +180,16 @@ export class ServerDescription { |
179 | 180 | * Determines if another `ServerDescription` is equal to this one per the rules defined |
180 | 181 | * in the {@link https://github.com/mongodb/specifications/blob/master/source/server-discovery-and-monitoring/server-discovery-and-monitoring.rst#serverdescription|SDAM spec} |
181 | 182 | */ |
182 | | - equals(other: ServerDescription): boolean { |
| 183 | + equals(other?: ServerDescription | null): boolean { |
| 184 | + // TODO(NODE-4510): Check ServerDescription equality logic for nullish topologyVersion meaning "greater than" |
183 | 185 | const topologyVersionsEqual = |
184 | | - this.topologyVersion === other.topologyVersion || |
185 | | - compareTopologyVersion(this.topologyVersion, other.topologyVersion) === 0; |
| 186 | + this.topologyVersion === other?.topologyVersion || |
| 187 | + compareTopologyVersion(this.topologyVersion, other?.topologyVersion) === 0; |
186 | 188 |
|
187 | | - const electionIdsEqual: boolean = |
188 | | - this.electionId && other.electionId |
189 | | - ? other.electionId && this.electionId.equals(other.electionId) |
190 | | - : this.electionId === other.electionId; |
| 189 | + const electionIdsEqual = |
| 190 | + this.electionId != null && other?.electionId != null |
| 191 | + ? compareObjectId(this.electionId, other.electionId) === 0 |
| 192 | + : this.electionId === other?.electionId; |
191 | 193 |
|
192 | 194 | return ( |
193 | 195 | other != null && |
@@ -254,19 +256,37 @@ function tagsStrictEqual(tags: TagSet, tags2: TagSet): boolean { |
254 | 256 | /** |
255 | 257 | * Compares two topology versions. |
256 | 258 | * |
257 | | - * @returns A negative number if `lhs` is older than `rhs`; positive if `lhs` is newer than `rhs`; 0 if they are equivalent. |
| 259 | + * 1. If the response topologyVersion is unset or the ServerDescription's |
| 260 | + * topologyVersion is null, the client MUST assume the response is more recent. |
| 261 | + * 1. If the response's topologyVersion.processId is not equal to the |
| 262 | + * ServerDescription's, the client MUST assume the response is more recent. |
| 263 | + * 1. If the response's topologyVersion.processId is equal to the |
| 264 | + * ServerDescription's, the client MUST use the counter field to determine |
| 265 | + * which topologyVersion is more recent. |
| 266 | + * |
| 267 | + * ```ts |
| 268 | + * currentTv < newTv === -1 |
| 269 | + * currentTv === newTv === 0 |
| 270 | + * currentTv > newTv === 1 |
| 271 | + * ``` |
258 | 272 | */ |
259 | | -export function compareTopologyVersion(lhs?: TopologyVersion, rhs?: TopologyVersion): number { |
260 | | - if (lhs == null || rhs == null) { |
| 273 | +export function compareTopologyVersion( |
| 274 | + currentTv?: TopologyVersion, |
| 275 | + newTv?: TopologyVersion |
| 276 | +): 0 | -1 | 1 { |
| 277 | + if (currentTv == null || newTv == null) { |
261 | 278 | return -1; |
262 | 279 | } |
263 | 280 |
|
264 | | - if (lhs.processId.equals(rhs.processId)) { |
265 | | - // tests mock counter as just number, but in a real situation counter should always be a Long |
266 | | - const lhsCounter = Long.isLong(lhs.counter) ? lhs.counter : Long.fromNumber(lhs.counter); |
267 | | - const rhsCounter = Long.isLong(rhs.counter) ? lhs.counter : Long.fromNumber(rhs.counter); |
268 | | - return lhsCounter.compare(rhsCounter); |
| 281 | + if (!currentTv.processId.equals(newTv.processId)) { |
| 282 | + return -1; |
269 | 283 | } |
270 | 284 |
|
271 | | - return -1; |
| 285 | + // TODO(NODE-2674): Preserve int64 sent from MongoDB |
| 286 | + const currentCounter = Long.isLong(currentTv.counter) |
| 287 | + ? currentTv.counter |
| 288 | + : Long.fromNumber(currentTv.counter); |
| 289 | + const newCounter = Long.isLong(newTv.counter) ? newTv.counter : Long.fromNumber(newTv.counter); |
| 290 | + |
| 291 | + return currentCounter.compare(newCounter); |
272 | 292 | } |
0 commit comments