Skip to content

Commit

Permalink
feat(NODE-6605): add error message when invalidating primary (#4340)
Browse files Browse the repository at this point in the history
Co-authored-by: Bailey Pearson <[email protected]>
  • Loading branch information
W-A-James and baileympearson authored Dec 9, 2024
1 parent ea8a33f commit 37613f1
Show file tree
Hide file tree
Showing 23 changed files with 187 additions and 101 deletions.
39 changes: 37 additions & 2 deletions src/error.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import type { Document } from './bson';
import type { Document, ObjectId } from './bson';
import {
type ClientBulkWriteError,
type ClientBulkWriteResult
} from './operations/client_bulk_write/common';
import type { ServerType } from './sdam/common';
import type { TopologyVersion } from './sdam/server_description';
import type { ServerDescription, TopologyVersion } from './sdam/server_description';
import type { TopologyDescription } from './sdam/topology_description';

/** @public */
Expand Down Expand Up @@ -340,6 +340,41 @@ export class MongoRuntimeError extends MongoDriverError {
}
}

/**
* An error generated when a primary server is marked stale, never directly thrown
*
* @public
* @category Error
*/
export class MongoStalePrimaryError extends MongoRuntimeError {
/**
* **Do not use this constructor!**
*
* Meant for internal use only.
*
* @remarks
* This class is only meant to be constructed within the driver. This constructor is
* not subject to semantic versioning compatibility guarantees and may change at any time.
*
* @public
**/
constructor(
serverDescription: ServerDescription,
maxSetVersion: number | null,
maxElectionId: ObjectId | null,
options?: { cause?: Error }
) {
super(
`primary marked stale due to electionId/setVersion mismatch: server setVersion: ${serverDescription.setVersion}, server electionId: ${serverDescription.electionId}, topology setVersion: ${maxSetVersion}, topology electionId: ${maxElectionId}`,
options
);
}

override get name(): string {
return 'MongoStalePrimaryError';
}
}

/**
* An error generated when a batch command is re-executed after one of the commands in the batch
* has failed
Expand Down
1 change: 1 addition & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ export {
MongoServerClosedError,
MongoServerError,
MongoServerSelectionError,
MongoStalePrimaryError,
MongoSystemError,
MongoTailableCursorError,
MongoTopologyClosedError,
Expand Down
3 changes: 3 additions & 0 deletions src/sdam/server_description.ts
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,10 @@ export class ServerDescription {
this.minRoundTripTime = options?.minRoundTripTime ?? 0;
this.lastUpdateTime = now();
this.lastWriteDate = hello?.lastWrite?.lastWriteDate ?? 0;
// NOTE: This actually builds the stack string instead of holding onto the getter and all its
// associated references. This is done to prevent a memory leak.
this.error = options.error ?? null;
this.error?.stack;
// TODO(NODE-2674): Preserve int64 sent from MongoDB
this.topologyVersion = this.error?.topologyVersion ?? hello?.topologyVersion ?? null;
this.setName = hello?.setName ?? null;
Expand Down
17 changes: 13 additions & 4 deletions src/sdam/topology_description.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { EJSON, type ObjectId } from '../bson';
import * as WIRE_CONSTANTS from '../cmap/wire_protocol/constants';
import { type MongoError, MongoRuntimeError } from '../error';
import { type MongoError, MongoRuntimeError, MongoStalePrimaryError } from '../error';
import { compareObjectId, shuffle } from '../utils';
import { ServerType, TopologyType } from './common';
import { ServerDescription } from './server_description';
Expand Down Expand Up @@ -400,7 +400,9 @@ function updateRsFromPrimary(
// replace serverDescription with a default ServerDescription of type "Unknown"
serverDescriptions.set(
serverDescription.address,
new ServerDescription(serverDescription.address)
new ServerDescription(serverDescription.address, undefined, {
error: new MongoStalePrimaryError(serverDescription, maxSetVersion, maxElectionId)
})
);

return [checkHasPrimary(serverDescriptions), setName, maxSetVersion, maxElectionId];
Expand All @@ -416,7 +418,9 @@ function updateRsFromPrimary(
// this primary is stale, we must remove it
serverDescriptions.set(
serverDescription.address,
new ServerDescription(serverDescription.address)
new ServerDescription(serverDescription.address, undefined, {
error: new MongoStalePrimaryError(serverDescription, maxSetVersion, maxElectionId)
})
);

return [checkHasPrimary(serverDescriptions), setName, maxSetVersion, maxElectionId];
Expand All @@ -438,7 +442,12 @@ function updateRsFromPrimary(
for (const [address, server] of serverDescriptions) {
if (server.type === ServerType.RSPrimary && server.address !== serverDescription.address) {
// Reset old primary's type to Unknown.
serverDescriptions.set(address, new ServerDescription(server.address));
serverDescriptions.set(
address,
new ServerDescription(server.address, undefined, {
error: new MongoStalePrimaryError(serverDescription, maxSetVersion, maxElectionId)
})
);

// There can only be one primary
break;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,8 @@
"a:27017": {
"type": "Unknown",
"setName": null,
"electionId": null
"electionId": null,
"error": "primary marked stale due to electionId/setVersion mismatch"
},
"b:27017": {
"type": "RSPrimary",
Expand Down Expand Up @@ -123,7 +124,8 @@
"a:27017": {
"type": "Unknown",
"setName": null,
"electionId": null
"electionId": null,
"error": "primary marked stale due to electionId/setVersion mismatch"
},
"b:27017": {
"type": "RSPrimary",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,8 @@ phases: [
"a:27017": {
type: "Unknown",
setName: ,
electionId:
electionId: ,
error: "primary marked stale due to electionId/setVersion mismatch"
},
"b:27017": {
type: "RSPrimary",
Expand Down Expand Up @@ -100,7 +101,8 @@ phases: [
"a:27017": {
type: "Unknown",
setName: ,
electionId:
electionId:,
error: "primary marked stale due to electionId/setVersion mismatch"
},
"b:27017": {
type: "RSPrimary",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,8 @@
"a:27017": {
"type": "Unknown",
"setName": null,
"electionId": null
"electionId": null,
"error": "primary marked stale due to electionId/setVersion mismatch"
},
"b:27017": {
"type": "RSPrimary",
Expand Down Expand Up @@ -123,7 +124,8 @@
"a:27017": {
"type": "Unknown",
"setName": null,
"electionId": null
"electionId": null,
"error": "primary marked stale due to electionId/setVersion mismatch"
},
"b:27017": {
"type": "RSPrimary",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,8 @@ phases: [
"a:27017": {
type: "Unknown",
setName: ,
electionId:
electionId:,
error: "primary marked stale due to electionId/setVersion mismatch"
},
"b:27017": {
type: "RSPrimary",
Expand Down Expand Up @@ -100,7 +101,8 @@ phases: [
"a:27017": {
type: "Unknown",
setName: ,
electionId:
electionId:,
error: "primary marked stale due to electionId/setVersion mismatch"
},
"b:27017": {
type: "RSPrimary",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@
"$oid": "000000000000000000000002"
},
"minWireVersion": 0,
"maxWireVersion": 21
"maxWireVersion": 7
}
]
],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,8 @@
"a:27017": {
"type": "Unknown",
"setName": null,
"electionId": null
"electionId": null,
"error": "primary marked stale due to electionId/setVersion mismatch"
},
"b:27017": {
"type": "RSPrimary",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@ phases: [
"a:27017": {
type: "Unknown",
setName: ,
electionId:
electionId:,
error: "primary marked stale due to electionId/setVersion mismatch"
},
"b:27017": {
type: "RSPrimary",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,8 @@
"a:27017": {
"type": "Unknown",
"setName": null,
"electionId": null
"electionId": null,
"error": "primary marked stale due to electionId/setVersion mismatch"
},
"b:27017": {
"type": "RSPrimary",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@ phases: [
"a:27017": {
type: "Unknown",
setName: ,
electionId:
electionId:,
error: "primary marked stale due to electionId/setVersion mismatch"
},
"b:27017": {
type: "RSPrimary",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,8 @@
"a:27017": {
"type": "Unknown",
"setName": null,
"electionId": null
"electionId": null,
"error": "primary marked stale due to electionId/setVersion mismatch"
},
"b:27017": {
"type": "RSPrimary",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,8 @@ phases: [
"a:27017": {
type: "Unknown",
setName: ,
electionId:
electionId:,
error: "primary marked stale due to electionId/setVersion mismatch"
},
"b:27017": {
type: "RSPrimary",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,8 @@
"a:27017": {
"type": "Unknown",
"setName": null,
"electionId": null
"electionId": null,
"error": "primary marked stale due to electionId/setVersion mismatch"
},
"b:27017": {
"type": "RSPrimary",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,8 @@ phases: [
"a:27017": {
type: "Unknown",
setName: ,
electionId:
electionId:,
error: "primary marked stale due to electionId/setVersion mismatch"
},
"b:27017": {
type: "RSPrimary",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,8 @@
"a:27017": {
"type": "Unknown",
"setName": null,
"electionId": null
"electionId": null,
"error": "primary marked stale due to electionId/setVersion mismatch"
},
"b:27017": {
"type": "RSPrimary",
Expand Down Expand Up @@ -117,7 +118,8 @@
"a:27017": {
"type": "Unknown",
"setName": null,
"electionId": null
"electionId": null,
"error": "primary marked stale due to electionId/setVersion mismatch"
},
"b:27017": {
"type": "RSPrimary",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,8 @@ phases: [
"a:27017": {
type: "Unknown",
setName: ,
electionId:
electionId:,
error: "primary marked stale due to electionId/setVersion mismatch"
},
"b:27017": {
type: "RSPrimary",
Expand Down Expand Up @@ -99,7 +100,8 @@ phases: [
"a:27017": {
type: "Unknown",
setName: ,
electionId:
electionId:,
error: "primary marked stale due to electionId/setVersion mismatch"
},
"b:27017": {
type: "RSPrimary",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,8 @@
"b:27017": {
"type": "Unknown",
"setName": null,
"electionId": null
"electionId": null,
"error": "primary marked stale due to electionId/setVersion mismatch"
}
},
"topologyType": "ReplicaSetWithPrimary",
Expand Down Expand Up @@ -128,7 +129,8 @@
"b:27017": {
"type": "Unknown",
"setName": null,
"electionId": null
"electionId": null,
"error": "primary marked stale due to electionId/setVersion mismatch"
}
},
"topologyType": "ReplicaSetWithPrimary",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,8 @@ phases: [
"b:27017": {
type: "Unknown",
setName: ,
electionId:
electionId:,
error: "primary marked stale due to electionId/setVersion mismatch"
}
},
topologyType: "ReplicaSetWithPrimary",
Expand Down Expand Up @@ -106,7 +107,8 @@ phases: [
"b:27017":{
type: "Unknown",
setName: ,
electionId:
electionId:,
error: "primary marked stale due to electionId/setVersion mismatch"
}
},
topologyType: "ReplicaSetWithPrimary",
Expand Down
Loading

0 comments on commit 37613f1

Please sign in to comment.