Skip to content

Commit 1b15469

Browse files
committed
feat(NODE-3424): use hello for monitoring commands
1 parent a07aa56 commit 1b15469

File tree

7 files changed

+24
-13
lines changed

7 files changed

+24
-13
lines changed

lib/core/connection/connect.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,10 @@ function performInitialHandshake(conn, options, _callback) {
113113
response.ismaster = response.isWritablePrimary;
114114
}
115115

116+
if (response.helloOk) {
117+
conn.helloOk = true;
118+
}
119+
116120
const supportedServerErr = checkSupportedServer(response, options);
117121
if (supportedServerErr) {
118122
callback(supportedServerErr);
@@ -169,6 +173,7 @@ function prepareHandshakeDocument(authContext, callback) {
169173

170174
const handshakeDoc = {
171175
[serverApi ? 'hello' : 'ismaster']: true,
176+
helloOk: true,
172177
client: options.metadata || makeClientMetadata(options),
173178
compression: compressors
174179
};

lib/core/connection/connection.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ class Connection extends EventEmitter {
9595
this.port = options.port || 27017;
9696
this.host = options.host || 'localhost';
9797
this.socketTimeout = typeof options.socketTimeout === 'number' ? options.socketTimeout : 0;
98+
this.helloOk = undefined;
9899

99100
// These values are inspected directly in tests, but maybe not necessary to keep around
100101
this.keepAlive = typeof options.keepAlive === 'boolean' ? options.keepAlive : true;

lib/core/sdam/monitor.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -204,9 +204,10 @@ function checkServer(monitor, callback) {
204204
const maxAwaitTimeMS = monitor.options.heartbeatFrequencyMS;
205205
const topologyVersion = monitor[kServer].description.topologyVersion;
206206
const isAwaitable = topologyVersion != null;
207-
const serverApi = monitor[kConnection].serverApi;
207+
const serverApi = monitor[kConnection].serverApi && monitor[kConnection].serverApi;
208+
const helloOk = monitor[kConnection].helloOk;
208209

209-
const cmd = { [serverApi ? 'hello' : 'ismaster']: true };
210+
const cmd = { [serverApi || helloOk ? 'hello' : 'ismaster']: true };
210211
const options = { socketTimeout: connectTimeoutMS };
211212

212213
if (isAwaitable) {

lib/core/sdam/server_description.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,7 @@ function parseServerType(ismaster) {
180180
if (ismaster.setName) {
181181
if (ismaster.hidden) {
182182
return ServerType.RSOther;
183-
} else if (ismaster.ismaster) {
183+
} else if (ismaster.ismaster || ismaster.isWritablePrimary) {
184184
return ServerType.RSPrimary;
185185
} else if (ismaster.secondary) {
186186
return ServerType.RSSecondary;

lib/core/topologies/replset_state.js

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -218,7 +218,8 @@ const isArbiter = ismaster => ismaster.arbiterOnly && ismaster.setName;
218218
ReplSetState.prototype.update = function(server) {
219219
var self = this;
220220
// Get the current ismaster
221-
var ismaster = server.lastIsMaster();
221+
const ismaster = server.lastIsMaster();
222+
const isWritablePrimary = ismaster && (ismaster.ismaster || ismaster.isWritablePrimary);
222223

223224
// Get the server name and lowerCase it
224225
var serverName = server.name.toLowerCase();
@@ -334,7 +335,7 @@ ReplSetState.prototype.update = function(server) {
334335
if (
335336
(ismaster.setName && ismaster.hidden) ||
336337
(ismaster.setName &&
337-
!ismaster.ismaster &&
338+
!isWritablePrimary &&
338339
!ismaster.secondary &&
339340
!ismaster.arbiterOnly &&
340341
!ismaster.passive)
@@ -357,7 +358,7 @@ ReplSetState.prototype.update = function(server) {
357358
//
358359
// Standalone server, destroy and return
359360
//
360-
if (ismaster && ismaster.ismaster && !ismaster.setName) {
361+
if (ismaster && isWritablePrimary && !ismaster.setName) {
361362
this.topologyType = this.primary ? TopologyType.ReplicaSetWithPrimary : TopologyType.Unknown;
362363
this.remove(server, { force: true });
363364
return false;
@@ -366,7 +367,7 @@ ReplSetState.prototype.update = function(server) {
366367
//
367368
// Server in maintanance mode
368369
//
369-
if (ismaster && !ismaster.ismaster && !ismaster.secondary && !ismaster.arbiterOnly) {
370+
if (ismaster && !isWritablePrimary && !ismaster.secondary && !ismaster.arbiterOnly) {
370371
this.remove(server, { force: true });
371372
return false;
372373
}
@@ -418,7 +419,7 @@ ReplSetState.prototype.update = function(server) {
418419
//
419420
// Primary handling
420421
//
421-
if (!this.primary && ismaster.ismaster && ismaster.setName) {
422+
if (!this.primary && isWritablePrimary && ismaster.setName) {
422423
var ismasterElectionId = server.lastIsMaster().electionId;
423424
if (this.setName && this.setName !== ismaster.setName) {
424425
this.topologyType = TopologyType.ReplicaSetNoPrimary;
@@ -481,7 +482,7 @@ ReplSetState.prototype.update = function(server) {
481482

482483
emitTopologyDescriptionChanged(self);
483484
return true;
484-
} else if (ismaster.ismaster && ismaster.setName) {
485+
} else if (isWritablePrimary && ismaster.setName) {
485486
// Get the electionIds
486487
var currentElectionId = self.set[self.primary.name.toLowerCase()].electionId;
487488
var currentSetVersion = self.set[self.primary.name.toLowerCase()].setVersion;

lib/core/topologies/shared.js

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -109,10 +109,12 @@ var getTopologyType = function(self, ismaster) {
109109
ismaster = self.ismaster;
110110
}
111111

112+
const isWritablePrimary = ismaster && (ismaster.ismaster || ismaster.isWritablePrimary);
113+
112114
if (!ismaster) return 'Unknown';
113-
if (ismaster.ismaster && ismaster.msg === 'isdbgrid') return 'Mongos';
114-
if (ismaster.ismaster && !ismaster.hosts) return 'Standalone';
115-
if (ismaster.ismaster) return 'RSPrimary';
115+
if (isWritablePrimary && ismaster.msg === 'isdbgrid') return 'Mongos';
116+
if (isWritablePrimary && !ismaster.hosts) return 'Standalone';
117+
if (isWritablePrimary) return 'RSPrimary';
116118
if (ismaster.secondary) return 'RSSecondary';
117119
if (ismaster.arbiterOnly) return 'RSArbiter';
118120
return 'Unknown';

test/functional/core/replset_state.test.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,8 @@ describe('ReplicaSet state', function() {
2222
description.match(/replicaSet URI option causes starting topology to be RSNP/) ||
2323
description.match(/Discover secondary with directConnection URI option/) ||
2424
description.match(/Discover ghost with directConnection URI option/) ||
25-
description.match(/topologyVersion/)
25+
description.match(/topologyVersion/) ||
26+
description.match(/Repeated isWritablePrimary response must be processed/)
2627
) {
2728
this.skip();
2829
return;

0 commit comments

Comments
 (0)