@@ -61,6 +61,7 @@ import {
61
61
STATE_CLOSING ,
62
62
STATE_CONNECTED ,
63
63
STATE_CONNECTING ,
64
+ STATE_UNITIALIZED ,
64
65
type TimerQueue ,
65
66
TopologyType
66
67
} from './common' ;
@@ -89,6 +90,7 @@ import { TopologyDescription } from './topology_description';
89
90
let globalTopologyCounter = 0 ;
90
91
91
92
const stateTransition = makeStateMachine ( {
93
+ [ STATE_UNITIALIZED ] : [ STATE_CONNECTING , STATE_CLOSING ] ,
92
94
[ STATE_CLOSED ] : [ STATE_CLOSED , STATE_CONNECTING ] ,
93
95
[ STATE_CONNECTING ] : [ STATE_CONNECTING , STATE_CLOSING , STATE_CONNECTED , STATE_CLOSED ] ,
94
96
[ STATE_CONNECTED ] : [ STATE_CONNECTED , STATE_CLOSING , STATE_CLOSED ] ,
@@ -215,7 +217,7 @@ export type TopologyEvents = {
215
217
*/
216
218
export class Topology extends TypedEventEmitter < TopologyEvents > {
217
219
/** @internal */
218
- s ! : TopologyPrivate ;
220
+ s : TopologyPrivate ;
219
221
/** @internal */
220
222
[ kWaitQueue ] : List < ServerSelectionRequest > ;
221
223
/** @internal */
@@ -262,6 +264,55 @@ export class Topology extends TypedEventEmitter<TopologyEvents> {
262
264
this . client = client ;
263
265
this . options = options ;
264
266
this [ kWaitQueue ] = new List ( ) ;
267
+
268
+ const topologyId = globalTopologyCounter ++ ;
269
+ this . s = {
270
+ // the id of this topology
271
+ id : topologyId ,
272
+ // passed in options
273
+ options,
274
+ seedlist : [ ] ,
275
+ // initial state
276
+ state : STATE_UNITIALIZED ,
277
+ // the topology description
278
+ description : new TopologyDescription ( TopologyType . Unknown ) ,
279
+ serverSelectionTimeoutMS : options . serverSelectionTimeoutMS ,
280
+ heartbeatFrequencyMS : options . heartbeatFrequencyMS ,
281
+ minHeartbeatFrequencyMS : options . minHeartbeatFrequencyMS ,
282
+ // a map of server instances to normalized addresses
283
+ servers : new Map ( ) ,
284
+ credentials : options ?. credentials ,
285
+ clusterTime : undefined ,
286
+
287
+ // timer management
288
+ connectionTimers : new Set < NodeJS . Timeout > ( ) ,
289
+ detectShardedTopology : ev => this . detectShardedTopology ( ev ) ,
290
+ detectSrvRecords : ev => this . detectSrvRecords ( ev )
291
+ } ;
292
+ this . mongoLogger = this . client . mongoLogger ;
293
+ this . component = 'topology' ;
294
+
295
+ if ( options . srvHost && ! options . loadBalanced ) {
296
+ this . s . srvPoller =
297
+ // @ts -expect-error: todo
298
+ options . srvPoller ??
299
+ new SrvPoller ( {
300
+ heartbeatFrequencyMS : this . s . heartbeatFrequencyMS ,
301
+ srvHost : options . srvHost ,
302
+ srvMaxHosts : options . srvMaxHosts ,
303
+ srvServiceName : options . srvServiceName
304
+ } ) ;
305
+
306
+ this . on ( Topology . TOPOLOGY_DESCRIPTION_CHANGED , this . s . detectShardedTopology ) ;
307
+ }
308
+ // Events can be emitted before initialization is complete so we have to
309
+ // save the reference to the topology on the client ASAP if the event handlers need to access it
310
+
311
+ this . once ( Topology . OPEN , ( ) => this . client . emit ( 'open' , this . client ) ) ;
312
+
313
+ for ( const event of MONGO_CLIENT_EVENTS ) {
314
+ this . on ( event , ( ...args : any [ ] ) => this . client . emit ( event , ...( args as any ) ) ) ;
315
+ }
265
316
}
266
317
267
318
async init ( ) {
@@ -337,7 +388,6 @@ export class Topology extends TypedEventEmitter<TopologyEvents> {
337
388
}
338
389
339
390
const topologyType = topologyTypeFromOptions ( options ) ;
340
- const topologyId = globalTopologyCounter ++ ;
341
391
342
392
const selectedHosts =
343
393
options . srvMaxHosts == null ||
@@ -351,64 +401,17 @@ export class Topology extends TypedEventEmitter<TopologyEvents> {
351
401
serverDescriptions . set ( hostAddress . toString ( ) , new ServerDescription ( hostAddress ) ) ;
352
402
}
353
403
354
- this . s = {
355
- // the id of this topology
356
- id : topologyId ,
357
- // passed in options
358
- options,
359
- // initial seedlist of servers to connect to
360
- seedlist,
361
- // initial state
362
- state : STATE_CLOSED ,
363
- // the topology description
364
- description : new TopologyDescription (
365
- topologyType ,
366
- serverDescriptions ,
367
- options . replicaSet ,
368
- undefined ,
369
- undefined ,
370
- undefined ,
371
- options
372
- ) ,
373
- serverSelectionTimeoutMS : options . serverSelectionTimeoutMS ,
374
- heartbeatFrequencyMS : options . heartbeatFrequencyMS ,
375
- minHeartbeatFrequencyMS : options . minHeartbeatFrequencyMS ,
376
- // a map of server instances to normalized addresses
377
- servers : new Map ( ) ,
378
- credentials : options ?. credentials ,
379
- clusterTime : undefined ,
380
-
381
- // timer management
382
- connectionTimers : new Set < NodeJS . Timeout > ( ) ,
383
- detectShardedTopology : ev => this . detectShardedTopology ( ev ) ,
384
- detectSrvRecords : ev => this . detectSrvRecords ( ev )
385
- } ;
386
-
387
- this . mongoLogger = this . client . mongoLogger ;
388
- this . component = 'topology' ;
389
-
390
- if ( options . srvHost && ! options . loadBalanced ) {
391
- this . s . srvPoller =
392
- // @ts -expect-error: todo
393
- options . srvPoller ??
394
- new SrvPoller ( {
395
- heartbeatFrequencyMS : this . s . heartbeatFrequencyMS ,
396
- srvHost : options . srvHost ,
397
- srvMaxHosts : options . srvMaxHosts ,
398
- srvServiceName : options . srvServiceName
399
- } ) ;
400
-
401
- this . on ( Topology . TOPOLOGY_DESCRIPTION_CHANGED , this . s . detectShardedTopology ) ;
402
- }
403
-
404
- // Events can be emitted before initialization is complete so we have to
405
- // save the reference to the topology on the client ASAP if the event handlers need to access it
406
-
407
- this . once ( Topology . OPEN , ( ) => this . client . emit ( 'open' , this . client ) ) ;
408
-
409
- for ( const event of MONGO_CLIENT_EVENTS ) {
410
- this . on ( event , ( ...args : any [ ] ) => this . client . emit ( event , ...( args as any ) ) ) ;
411
- }
404
+ this . s . description = new TopologyDescription (
405
+ topologyType ,
406
+ serverDescriptions ,
407
+ options . replicaSet ,
408
+ undefined ,
409
+ undefined ,
410
+ undefined ,
411
+ options
412
+ ) ;
413
+ // initial seedlist of servers to connect to
414
+ this . s . seedlist = seedlist ;
412
415
}
413
416
414
417
private detectShardedTopology ( event : TopologyDescriptionChangedEvent ) {
@@ -510,7 +513,7 @@ export class Topology extends TypedEventEmitter<TopologyEvents> {
510
513
selector : string | ReadPreference | ServerSelector ,
511
514
options : SelectServerOptions
512
515
) : Promise < Server > {
513
- const shouldInitialize = this . s == null ;
516
+ const shouldInitialize = this . s . state === STATE_UNITIALIZED ;
514
517
if ( shouldInitialize ) {
515
518
await this . init ( ) ;
516
519
this . stateTransition ( STATE_CONNECTING ) ;
0 commit comments