Skip to content

Commit 8e56872

Browse files
authored
fix(NODE-5750): RTTPinger always sends legacy hello (#3922)
1 parent 6266734 commit 8e56872

File tree

4 files changed

+217
-43
lines changed

4 files changed

+217
-43
lines changed

Diff for: src/sdam/monitor.ts

+26-26
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,6 @@ const kConnection = Symbol('connection');
2626
/** @internal */
2727
const kCancellationToken = Symbol('cancellationToken');
2828
/** @internal */
29-
const kRTTPinger = Symbol('rttPinger');
30-
/** @internal */
3129
const kRoundTripTime = Symbol('roundTripTime');
3230

3331
const STATE_IDLE = 'idle';
@@ -81,7 +79,7 @@ export class Monitor extends TypedEventEmitter<MonitorEvents> {
8179
[kCancellationToken]: CancellationToken;
8280
/** @internal */
8381
[kMonitorId]?: MonitorInterval;
84-
[kRTTPinger]?: RTTPinger;
82+
rttPinger?: RTTPinger;
8583

8684
get connection(): Connection | undefined {
8785
return this[kConnection];
@@ -198,8 +196,8 @@ function resetMonitorState(monitor: Monitor) {
198196
monitor[kMonitorId]?.stop();
199197
monitor[kMonitorId] = undefined;
200198

201-
monitor[kRTTPinger]?.close();
202-
monitor[kRTTPinger] = undefined;
199+
monitor.rttPinger?.close();
200+
monitor.rttPinger = undefined;
203201

204202
monitor[kCancellationToken].emit('cancel');
205203

@@ -252,8 +250,8 @@ function checkServer(monitor: Monitor, callback: Callback<Document | null>) {
252250
}
253251
: { socketTimeoutMS: connectTimeoutMS };
254252

255-
if (isAwaitable && monitor[kRTTPinger] == null) {
256-
monitor[kRTTPinger] = new RTTPinger(
253+
if (isAwaitable && monitor.rttPinger == null) {
254+
monitor.rttPinger = new RTTPinger(
257255
monitor[kCancellationToken],
258256
Object.assign(
259257
{ heartbeatFrequencyMS: monitor.options.heartbeatFrequencyMS },
@@ -272,9 +270,10 @@ function checkServer(monitor: Monitor, callback: Callback<Document | null>) {
272270
hello.isWritablePrimary = hello[LEGACY_HELLO_COMMAND];
273271
}
274272

275-
const rttPinger = monitor[kRTTPinger];
276273
const duration =
277-
isAwaitable && rttPinger ? rttPinger.roundTripTime : calculateDurationInMs(start);
274+
isAwaitable && monitor.rttPinger
275+
? monitor.rttPinger.roundTripTime
276+
: calculateDurationInMs(start);
278277

279278
monitor.emit(
280279
Server.SERVER_HEARTBEAT_SUCCEEDED,
@@ -290,8 +289,8 @@ function checkServer(monitor: Monitor, callback: Callback<Document | null>) {
290289
);
291290
start = now();
292291
} else {
293-
monitor[kRTTPinger]?.close();
294-
monitor[kRTTPinger] = undefined;
292+
monitor.rttPinger?.close();
293+
monitor.rttPinger = undefined;
295294

296295
callback(undefined, hello);
297296
}
@@ -384,7 +383,7 @@ export interface RTTPingerOptions extends ConnectionOptions {
384383
/** @internal */
385384
export class RTTPinger {
386385
/** @internal */
387-
[kConnection]?: Connection;
386+
connection?: Connection;
388387
/** @internal */
389388
[kCancellationToken]: CancellationToken;
390389
/** @internal */
@@ -394,7 +393,7 @@ export class RTTPinger {
394393
closed: boolean;
395394

396395
constructor(cancellationToken: CancellationToken, options: RTTPingerOptions) {
397-
this[kConnection] = undefined;
396+
this.connection = undefined;
398397
this[kCancellationToken] = cancellationToken;
399398
this[kRoundTripTime] = 0;
400399
this.closed = false;
@@ -411,8 +410,8 @@ export class RTTPinger {
411410
this.closed = true;
412411
clearTimeout(this[kMonitorId]);
413412

414-
this[kConnection]?.destroy({ force: true });
415-
this[kConnection] = undefined;
413+
this.connection?.destroy({ force: true });
414+
this.connection = undefined;
416415
}
417416
}
418417

@@ -431,8 +430,8 @@ function measureRoundTripTime(rttPinger: RTTPinger, options: RTTPingerOptions) {
431430
return;
432431
}
433432

434-
if (rttPinger[kConnection] == null) {
435-
rttPinger[kConnection] = conn;
433+
if (rttPinger.connection == null) {
434+
rttPinger.connection = conn;
436435
}
437436

438437
rttPinger[kRoundTripTime] = calculateDurationInMs(start);
@@ -442,11 +441,11 @@ function measureRoundTripTime(rttPinger: RTTPinger, options: RTTPingerOptions) {
442441
);
443442
}
444443

445-
const connection = rttPinger[kConnection];
444+
const connection = rttPinger.connection;
446445
if (connection == null) {
447446
connect(options, (err, conn) => {
448447
if (err) {
449-
rttPinger[kConnection] = undefined;
448+
rttPinger.connection = undefined;
450449
rttPinger[kRoundTripTime] = 0;
451450
return;
452451
}
@@ -457,15 +456,16 @@ function measureRoundTripTime(rttPinger: RTTPinger, options: RTTPingerOptions) {
457456
return;
458457
}
459458

460-
connection.command(ns('admin.$cmd'), { [LEGACY_HELLO_COMMAND]: 1 }, undefined, err => {
461-
if (err) {
462-
rttPinger[kConnection] = undefined;
459+
const commandName =
460+
connection.serverApi?.version || connection.helloOk ? 'hello' : LEGACY_HELLO_COMMAND;
461+
connection.commandAsync(ns('admin.$cmd'), { [commandName]: 1 }, undefined).then(
462+
() => measureAndReschedule(),
463+
() => {
464+
rttPinger.connection?.destroy({ force: true });
465+
rttPinger.connection = undefined;
463466
rttPinger[kRoundTripTime] = 0;
464-
return;
465467
}
466-
467-
measureAndReschedule();
468-
});
468+
);
469469
}
470470

471471
/**

Diff for: src/sdam/server.ts

+10-14
Original file line numberDiff line numberDiff line change
@@ -74,9 +74,6 @@ const stateTransition = makeStateMachine({
7474
[STATE_CLOSING]: [STATE_CLOSING, STATE_CLOSED]
7575
});
7676

77-
/** @internal */
78-
const kMonitor = Symbol('monitor');
79-
8077
/** @internal */
8178
export type ServerOptions = Omit<ConnectionPoolOptions, 'id' | 'generation' | 'hostAddress'> &
8279
MonitorOptions;
@@ -119,7 +116,7 @@ export class Server extends TypedEventEmitter<ServerEvents> {
119116
serverApi?: ServerApi;
120117
hello?: Document;
121118
commandAsync: (ns: MongoDBNamespace, cmd: Document, options: CommandOptions) => Promise<Document>;
122-
[kMonitor]: Monitor | null;
119+
monitor: Monitor | null;
123120

124121
/** @event */
125122
static readonly SERVER_HEARTBEAT_STARTED = SERVER_HEARTBEAT_STARTED;
@@ -175,22 +172,21 @@ export class Server extends TypedEventEmitter<ServerEvents> {
175172
});
176173

177174
if (this.loadBalanced) {
178-
this[kMonitor] = null;
175+
this.monitor = null;
179176
// monitoring is disabled in load balancing mode
180177
return;
181178
}
182179

183180
// create the monitor
184181
// TODO(NODE-4144): Remove new variable for type narrowing
185-
const monitor = new Monitor(this, this.s.options);
186-
this[kMonitor] = monitor;
182+
this.monitor = new Monitor(this, this.s.options);
187183

188184
for (const event of HEARTBEAT_EVENTS) {
189-
monitor.on(event, (e: any) => this.emit(event, e));
185+
this.monitor.on(event, (e: any) => this.emit(event, e));
190186
}
191187

192-
monitor.on('resetServer', (error: MongoError) => markServerUnknown(this, error));
193-
monitor.on(Server.SERVER_HEARTBEAT_SUCCEEDED, (event: ServerHeartbeatSucceededEvent) => {
188+
this.monitor.on('resetServer', (error: MongoError) => markServerUnknown(this, error));
189+
this.monitor.on(Server.SERVER_HEARTBEAT_SUCCEEDED, (event: ServerHeartbeatSucceededEvent) => {
194190
this.emit(
195191
Server.DESCRIPTION_RECEIVED,
196192
new ServerDescription(this.description.hostAddress, event.reply, {
@@ -246,7 +242,7 @@ export class Server extends TypedEventEmitter<ServerEvents> {
246242
// a load balancer. It never transitions out of this state and
247243
// has no monitor.
248244
if (!this.loadBalanced) {
249-
this[kMonitor]?.connect();
245+
this.monitor?.connect();
250246
} else {
251247
stateTransition(this, STATE_CONNECTED);
252248
this.emit(Server.CONNECT, this);
@@ -272,7 +268,7 @@ export class Server extends TypedEventEmitter<ServerEvents> {
272268
stateTransition(this, STATE_CLOSING);
273269

274270
if (!this.loadBalanced) {
275-
this[kMonitor]?.close();
271+
this.monitor?.close();
276272
}
277273

278274
this.pool.close(options, err => {
@@ -290,7 +286,7 @@ export class Server extends TypedEventEmitter<ServerEvents> {
290286
*/
291287
requestCheck(): void {
292288
if (!this.loadBalanced) {
293-
this[kMonitor]?.requestCheck();
289+
this.monitor?.requestCheck();
294290
}
295291
}
296292

@@ -465,7 +461,7 @@ function markServerUnknown(server: Server, error?: MongoServerError) {
465461
}
466462

467463
if (error instanceof MongoNetworkError && !(error instanceof MongoNetworkTimeoutError)) {
468-
server[kMonitor]?.reset();
464+
server.monitor?.reset();
469465
}
470466

471467
server.emit(

0 commit comments

Comments
 (0)