Skip to content

Commit de9def7

Browse files
committed
undo driver changes
1 parent 2989074 commit de9def7

File tree

3 files changed

+89
-102
lines changed

3 files changed

+89
-102
lines changed

src/sdam/topology.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -317,6 +317,7 @@ export class Topology extends TypedEventEmitter<TopologyEvents> {
317317
options.replicaSet,
318318
undefined,
319319
undefined,
320+
undefined,
320321
options
321322
),
322323
serverSelectionTimeoutMS: options.serverSelectionTimeoutMS,

src/sdam/topology_description.ts

Lines changed: 86 additions & 102 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { ObjectId } from '../bson';
1+
import type { Document, ObjectId } from '../bson';
22
import * as WIRE_CONSTANTS from '../cmap/wire_protocol/constants';
33
import { MongoError, MongoRuntimeError } from '../error';
44
import { shuffle } from '../utils';
@@ -33,6 +33,8 @@ export interface TopologyDescriptionOptions {
3333
export class TopologyDescription {
3434
type: TopologyType;
3535
setName?: string;
36+
maxSetVersion?: number;
37+
maxElectionId?: ObjectId;
3638
servers: Map<string, ServerDescription>;
3739
stale: boolean;
3840
compatible: boolean;
@@ -42,28 +44,23 @@ export class TopologyDescription {
4244
localThresholdMS: number;
4345
commonWireVersion?: number;
4446

45-
maxElectionIdSetVersionPair: ElectionIdSetVersionPair;
46-
47-
get maxElectionId(): ObjectId | undefined {
48-
return this.maxElectionIdSetVersionPair.electionId;
49-
}
50-
get maxSetVersion(): number | undefined {
51-
return this.maxElectionIdSetVersionPair.setVersion;
52-
}
53-
5447
/**
5548
* Create a TopologyDescription
5649
*/
5750
constructor(
5851
topologyType: TopologyType,
5952
serverDescriptions?: Map<string, ServerDescription>,
6053
setName?: string,
61-
maxElectionIdSetVersionPair?: ElectionIdSetVersionPair,
54+
maxSetVersion?: number,
55+
maxElectionId?: ObjectId,
6256
commonWireVersion?: number,
6357
options?: TopologyDescriptionOptions
6458
) {
6559
options = options ?? {};
6660

61+
// TODO: consider assigning all these values to a temporary value `s` which
62+
// we use `Object.freeze` on, ensuring the internal state of this type
63+
// is immutable.
6764
this.type = topologyType ?? TopologyType.Unknown;
6865
this.servers = serverDescriptions ?? new Map();
6966
this.stale = false;
@@ -75,10 +72,13 @@ export class TopologyDescription {
7572
this.setName = setName;
7673
}
7774

78-
this.maxElectionIdSetVersionPair = {
79-
electionId: maxElectionIdSetVersionPair?.electionId,
80-
setVersion: maxElectionIdSetVersionPair?.setVersion
81-
};
75+
if (maxSetVersion) {
76+
this.maxSetVersion = maxSetVersion;
77+
}
78+
79+
if (maxElectionId) {
80+
this.maxElectionId = maxElectionId;
81+
}
8282

8383
if (commonWireVersion) {
8484
this.commonWireVersion = commonWireVersion;
@@ -134,8 +134,6 @@ export class TopologyDescription {
134134
);
135135
}
136136
}
137-
138-
Object.freeze(this);
139137
}
140138

141139
/**
@@ -188,7 +186,8 @@ export class TopologyDescription {
188186
this.type,
189187
serverDescriptions,
190188
this.setName,
191-
this.maxElectionIdSetVersionPair,
189+
this.maxSetVersion,
190+
this.maxElectionId,
192191
this.commonWireVersion,
193192
{ heartbeatFrequencyMS: this.heartbeatFrequencyMS, localThresholdMS: this.localThresholdMS }
194193
);
@@ -202,7 +201,7 @@ export class TopologyDescription {
202201
const address = serverDescription.address;
203202

204203
// potentially mutated values
205-
let { type: topologyType, setName, maxElectionIdSetVersionPair, commonWireVersion } = this;
204+
let { type: topologyType, setName, maxSetVersion, maxElectionId, commonWireVersion } = this;
206205

207206
if (serverDescription.setName && setName && serverDescription.setName !== setName) {
208207
serverDescription = new ServerDescription(address, undefined);
@@ -229,7 +228,8 @@ export class TopologyDescription {
229228
TopologyType.Single,
230229
serverDescriptions,
231230
setName,
232-
maxElectionIdSetVersionPair,
231+
maxSetVersion,
232+
maxElectionId,
233233
commonWireVersion,
234234
{ heartbeatFrequencyMS: this.heartbeatFrequencyMS, localThresholdMS: this.localThresholdMS }
235235
);
@@ -258,13 +258,15 @@ export class TopologyDescription {
258258
const result = updateRsFromPrimary(
259259
serverDescriptions,
260260
serverDescription,
261-
maxElectionIdSetVersionPair,
262-
setName
261+
setName,
262+
maxSetVersion,
263+
maxElectionId
263264
);
264265

265-
topologyType = result.topologyType;
266-
setName = result.setName;
267-
maxElectionIdSetVersionPair = result.electionIdSetVersionPair;
266+
topologyType = result[0];
267+
setName = result[1];
268+
maxSetVersion = result[2];
269+
maxElectionId = result[3];
268270
} else if (NON_PRIMARY_RS_MEMBERS.has(serverType)) {
269271
const result = updateRsNoPrimaryFromMember(serverDescriptions, serverDescription, setName);
270272
topologyType = result[0];
@@ -280,13 +282,15 @@ export class TopologyDescription {
280282
const result = updateRsFromPrimary(
281283
serverDescriptions,
282284
serverDescription,
283-
maxElectionIdSetVersionPair,
284-
setName
285+
setName,
286+
maxSetVersion,
287+
maxElectionId
285288
);
286289

287-
topologyType = result.topologyType;
288-
setName = result.setName;
289-
maxElectionIdSetVersionPair = result.electionIdSetVersionPair;
290+
topologyType = result[0];
291+
setName = result[1];
292+
maxSetVersion = result[2];
293+
maxElectionId = result[3];
290294
} else if (NON_PRIMARY_RS_MEMBERS.has(serverType)) {
291295
topologyType = updateRsWithPrimaryFromMember(
292296
serverDescriptions,
@@ -302,7 +306,8 @@ export class TopologyDescription {
302306
topologyType,
303307
serverDescriptions,
304308
setName,
305-
maxElectionIdSetVersionPair,
309+
maxSetVersion,
310+
maxElectionId,
306311
commonWireVersion,
307312
{ heartbeatFrequencyMS: this.heartbeatFrequencyMS, localThresholdMS: this.localThresholdMS }
308313
);
@@ -359,54 +364,65 @@ function topologyTypeForServerType(serverType: ServerType): TopologyType {
359364
}
360365
}
361366

362-
function compareObjectId(oid1: ObjectId, oid2: ObjectId): 0 | 1 | -1 {
363-
const res = oid1.id.compare(oid2.id);
364-
return res === 0 ? 0 : res > 0 ? 1 : -1;
367+
// TODO: improve these docs when ObjectId is properly typed
368+
function compareObjectId(oid1: Document, oid2: Document): number {
369+
if (oid1 == null) {
370+
return -1;
371+
}
372+
373+
if (oid2 == null) {
374+
return 1;
375+
}
376+
377+
if (oid1.id instanceof Buffer && oid2.id instanceof Buffer) {
378+
const oid1Buffer = oid1.id;
379+
const oid2Buffer = oid2.id;
380+
return oid1Buffer.compare(oid2Buffer);
381+
}
382+
383+
const oid1String = oid1.toString();
384+
const oid2String = oid2.toString();
385+
return oid1String.localeCompare(oid2String);
365386
}
366387

367388
function updateRsFromPrimary(
368389
serverDescriptions: Map<string, ServerDescription>,
369390
serverDescription: ServerDescription,
370-
maxElectionIdSetVersionPair: ElectionIdSetVersionPair,
371-
setName?: string
372-
): {
373-
topologyType: TopologyType;
374-
setName?: string;
375-
electionIdSetVersionPair: ElectionIdSetVersionPair;
376-
} {
391+
setName?: string,
392+
maxSetVersion?: number,
393+
maxElectionId?: ObjectId
394+
): [TopologyType, string?, number?, ObjectId?] {
377395
setName = setName || serverDescription.setName;
378396
if (setName !== serverDescription.setName) {
379397
serverDescriptions.delete(serverDescription.address);
380-
return {
381-
topologyType: checkHasPrimary(serverDescriptions),
382-
setName,
383-
electionIdSetVersionPair: maxElectionIdSetVersionPair
384-
};
398+
return [checkHasPrimary(serverDescriptions), setName, maxSetVersion, maxElectionId];
385399
}
386400

387-
const incomingElectionIdSetVersionPair = {
388-
electionId: serverDescription.electionId,
389-
setVersion: serverDescription.setVersion
390-
};
391-
392-
const newMaxElectionIdSetVersionPair = greaterElectionIdSetVersionPair(
393-
maxElectionIdSetVersionPair,
394-
incomingElectionIdSetVersionPair
395-
);
396-
397-
if (newMaxElectionIdSetVersionPair !== maxElectionIdSetVersionPair) {
398-
// The primary we know about has become stale
399-
// make new ServerDescription for that address
400-
// this makes it unknown
401-
serverDescriptions.set(
402-
serverDescription.address,
403-
new ServerDescription(serverDescription.address)
404-
);
405-
return {
406-
topologyType: checkHasPrimary(serverDescriptions),
407-
setName,
408-
electionIdSetVersionPair: newMaxElectionIdSetVersionPair
409-
};
401+
const electionId = serverDescription.electionId ? serverDescription.electionId : null;
402+
if (serverDescription.setVersion && electionId) {
403+
if (maxSetVersion && maxElectionId) {
404+
if (
405+
maxSetVersion > serverDescription.setVersion ||
406+
compareObjectId(maxElectionId, electionId) > 0
407+
) {
408+
// this primary is stale, we must remove it
409+
serverDescriptions.set(
410+
serverDescription.address,
411+
new ServerDescription(serverDescription.address)
412+
);
413+
414+
return [checkHasPrimary(serverDescriptions), setName, maxSetVersion, maxElectionId];
415+
}
416+
}
417+
418+
maxElectionId = serverDescription.electionId;
419+
}
420+
421+
if (
422+
serverDescription.setVersion != null &&
423+
(maxSetVersion == null || serverDescription.setVersion > maxSetVersion)
424+
) {
425+
maxSetVersion = serverDescription.setVersion;
410426
}
411427

412428
// We've heard from the primary. Is it the same primary as before?
@@ -436,11 +452,7 @@ function updateRsFromPrimary(
436452
serverDescriptions.delete(address);
437453
});
438454

439-
return {
440-
topologyType: checkHasPrimary(serverDescriptions),
441-
setName,
442-
electionIdSetVersionPair: newMaxElectionIdSetVersionPair
443-
};
455+
return [checkHasPrimary(serverDescriptions), setName, maxSetVersion, maxElectionId];
444456
}
445457

446458
function updateRsWithPrimaryFromMember(
@@ -497,31 +509,3 @@ function checkHasPrimary(serverDescriptions: Map<string, ServerDescription>): To
497509

498510
return TopologyType.ReplicaSetNoPrimary;
499511
}
500-
501-
interface ElectionIdSetVersionPair {
502-
electionId?: ObjectId;
503-
setVersion?: number;
504-
}
505-
506-
const OID_ZERO = new ObjectId('00'.repeat(12));
507-
508-
function greaterElectionIdSetVersionPair(
509-
a: ElectionIdSetVersionPair,
510-
b: ElectionIdSetVersionPair
511-
): ElectionIdSetVersionPair {
512-
if (compareObjectId(a.electionId ?? OID_ZERO, b.electionId ?? OID_ZERO) === 0) {
513-
// ObjectIds are equal so we have to check setVersion
514-
if ((a.setVersion ?? -1) >= (b.setVersion ?? -1)) {
515-
if (a.electionId == null && a.setVersion == null) {
516-
return a;
517-
}
518-
return a;
519-
} else {
520-
return b;
521-
}
522-
} else if (compareObjectId(a.electionId ?? OID_ZERO, b.electionId ?? OID_ZERO) === 1) {
523-
return a;
524-
} else {
525-
return b;
526-
}
527-
}

test/integration/server-discovery-and-monitoring/electionId_precedence.test.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
//TODO!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2+
/* eslint-disable @typescript-eslint/no-unused-vars */
13
import { expect } from 'chai';
24

35
import { MongoClient } from '../../../src';

0 commit comments

Comments
 (0)