@@ -23,8 +23,6 @@ const kServer = Symbol('server');
23
23
/** @internal */
24
24
const kMonitorId = Symbol ( 'monitorId' ) ;
25
25
/** @internal */
26
- const kConnection = Symbol ( 'connection' ) ;
27
- /** @internal */
28
26
const kCancellationToken = Symbol ( 'cancellationToken' ) ;
29
27
/** @internal */
30
28
const kRoundTripTime = Symbol ( 'roundTripTime' ) ;
@@ -94,21 +92,17 @@ export class Monitor extends TypedEventEmitter<MonitorEvents> {
94
92
connectOptions : ConnectionOptions ;
95
93
isRunningInFaasEnv : boolean ;
96
94
[ kServer ] : Server ;
97
- [ kConnection ] ? : Connection ;
95
+ connection : Connection | null ;
98
96
[ kCancellationToken ] : CancellationToken ;
99
97
/** @internal */
100
98
[ kMonitorId ] ?: MonitorInterval ;
101
99
rttPinger ?: RTTPinger ;
102
100
103
- get connection ( ) : Connection | undefined {
104
- return this [ kConnection ] ;
105
- }
106
-
107
101
constructor ( server : Server , options : MonitorOptions ) {
108
102
super ( ) ;
109
103
110
104
this [ kServer ] = server ;
111
- this [ kConnection ] = undefined ;
105
+ this . connection = null ;
112
106
this [ kCancellationToken ] = new CancellationToken ( ) ;
113
107
this [ kCancellationToken ] . setMaxListeners ( Infinity ) ;
114
108
this [ kMonitorId ] = undefined ;
@@ -219,8 +213,8 @@ function resetMonitorState(monitor: Monitor) {
219
213
220
214
monitor [ kCancellationToken ] . emit ( 'cancel' ) ;
221
215
222
- monitor [ kConnection ] ?. destroy ( { force : true } ) ;
223
- monitor [ kConnection ] = undefined ;
216
+ monitor . connection ?. destroy ( { force : true } ) ;
217
+ monitor . connection = null ;
224
218
}
225
219
226
220
function useStreamingProtocol ( monitor : Monitor , topologyVersion : TopologyVersion | null ) : boolean {
@@ -241,16 +235,17 @@ function useStreamingProtocol(monitor: Monitor, topologyVersion: TopologyVersion
241
235
242
236
function checkServer ( monitor : Monitor , callback : Callback < Document | null > ) {
243
237
let start = now ( ) ;
238
+ let awaited : boolean ;
244
239
const topologyVersion = monitor [ kServer ] . description . topologyVersion ;
245
240
const isAwaitable = useStreamingProtocol ( monitor , topologyVersion ) ;
246
241
monitor . emit (
247
242
Server . SERVER_HEARTBEAT_STARTED ,
248
243
new ServerHeartbeatStartedEvent ( monitor . address , isAwaitable )
249
244
) ;
250
245
251
- function failureHandler ( err : Error , awaited : boolean ) {
252
- monitor [ kConnection ] ?. destroy ( { force : true } ) ;
253
- monitor [ kConnection ] = undefined ;
246
+ function onHeartbeatFailed ( err : Error ) {
247
+ monitor . connection ?. destroy ( { force : true } ) ;
248
+ monitor . connection = null ;
254
249
255
250
monitor . emit (
256
251
Server . SERVER_HEARTBEAT_FAILED ,
@@ -269,7 +264,39 @@ function checkServer(monitor: Monitor, callback: Callback<Document | null>) {
269
264
callback ( err ) ;
270
265
}
271
266
272
- const connection = monitor [ kConnection ] ;
267
+ function onHeartbeatSucceeded ( hello : Document ) {
268
+ if ( ! ( 'isWritablePrimary' in hello ) ) {
269
+ // Provide hello-style response document.
270
+ hello . isWritablePrimary = hello [ LEGACY_HELLO_COMMAND ] ;
271
+ }
272
+
273
+ const duration =
274
+ isAwaitable && monitor . rttPinger
275
+ ? monitor . rttPinger . roundTripTime
276
+ : calculateDurationInMs ( start ) ;
277
+
278
+ monitor . emit (
279
+ Server . SERVER_HEARTBEAT_SUCCEEDED ,
280
+ new ServerHeartbeatSucceededEvent ( monitor . address , duration , hello , isAwaitable )
281
+ ) ;
282
+
283
+ // If we are using the streaming protocol then we immediately issue another 'started'
284
+ // event, otherwise the "check" is complete and return to the main monitor loop.
285
+ if ( isAwaitable ) {
286
+ monitor . emit (
287
+ Server . SERVER_HEARTBEAT_STARTED ,
288
+ new ServerHeartbeatStartedEvent ( monitor . address , true )
289
+ ) ;
290
+ start = now ( ) ;
291
+ } else {
292
+ monitor . rttPinger ?. close ( ) ;
293
+ monitor . rttPinger = undefined ;
294
+
295
+ callback ( undefined , hello ) ;
296
+ }
297
+ }
298
+
299
+ const { connection } = monitor ;
273
300
if ( connection && ! connection . closed ) {
274
301
const { serverApi, helloOk } = connection ;
275
302
const connectTimeoutMS = monitor . options . connectTimeoutMS ;
@@ -299,51 +326,29 @@ function checkServer(monitor: Monitor, callback: Callback<Document | null>) {
299
326
) ;
300
327
}
301
328
302
- connection . command ( ns ( 'admin.$cmd' ) , cmd , options , ( err , hello ) => {
303
- if ( err ) {
304
- return failureHandler ( err , isAwaitable ) ;
305
- }
306
-
307
- if ( ! ( 'isWritablePrimary' in hello ) ) {
308
- // Provide hello-style response document.
309
- hello . isWritablePrimary = hello [ LEGACY_HELLO_COMMAND ] ;
310
- }
311
-
312
- const duration =
313
- isAwaitable && monitor . rttPinger
314
- ? monitor . rttPinger . roundTripTime
315
- : calculateDurationInMs ( start ) ;
316
-
317
- monitor . emit (
318
- Server . SERVER_HEARTBEAT_SUCCEEDED ,
319
- new ServerHeartbeatSucceededEvent ( monitor . address , duration , hello , isAwaitable )
320
- ) ;
329
+ if ( isAwaitable ) {
330
+ awaited = true ;
331
+ return connection . exhaustCommand ( ns ( 'admin.$cmd' ) , cmd , options , ( error , hello ) => {
332
+ if ( error ) return onHeartbeatFailed ( error ) ;
333
+ return onHeartbeatSucceeded ( hello ) ;
334
+ } ) ;
335
+ }
321
336
322
- // If we are using the streaming protocol then we immediately issue another 'started'
323
- // event, otherwise the "check" is complete and return to the main monitor loop.
324
- if ( isAwaitable ) {
325
- monitor . emit (
326
- Server . SERVER_HEARTBEAT_STARTED ,
327
- new ServerHeartbeatStartedEvent ( monitor . address , true )
328
- ) ;
329
- start = now ( ) ;
330
- } else {
331
- monitor . rttPinger ?. close ( ) ;
332
- monitor . rttPinger = undefined ;
333
-
334
- callback ( undefined , hello ) ;
335
- }
336
- } ) ;
337
+ awaited = false ;
338
+ connection
339
+ . commandAsync ( ns ( 'admin.$cmd' ) , cmd , options )
340
+ . then ( onHeartbeatSucceeded , onHeartbeatFailed ) ;
337
341
338
342
return ;
339
343
}
340
344
341
345
// connecting does an implicit `hello`
342
346
connect ( monitor . connectOptions , ( err , conn ) => {
343
347
if ( err ) {
344
- monitor [ kConnection ] = undefined ;
348
+ monitor . connection = null ;
345
349
346
- failureHandler ( err , false ) ;
350
+ awaited = false ;
351
+ onHeartbeatFailed ( err ) ;
347
352
return ;
348
353
}
349
354
@@ -357,7 +362,7 @@ function checkServer(monitor: Monitor, callback: Callback<Document | null>) {
357
362
return ;
358
363
}
359
364
360
- monitor [ kConnection ] = conn ;
365
+ monitor . connection = conn ;
361
366
monitor . emit (
362
367
Server . SERVER_HEARTBEAT_SUCCEEDED ,
363
368
new ServerHeartbeatSucceededEvent (
0 commit comments