@@ -449,54 +449,65 @@ export class MongoClient extends TypedEventEmitter<MongoClientEvents> {
449
449
}
450
450
451
451
return maybeCallback ( async ( ) => {
452
- if ( this . topology && this . topology . isConnected ( ) ) {
452
+ try {
453
+ if ( this . connectionLock ) return await this . connectionLock ;
454
+
455
+ this . connectionLock = this . _connect ( ) ;
456
+ await this . connectionLock ;
453
457
return this ;
458
+ } finally {
459
+ this . connectionLock = undefined ;
454
460
}
461
+ } , callback ) ;
462
+ }
455
463
456
- const options = this [ kOptions ] ;
464
+ private async _connect ( ) : Promise < this> {
465
+ if ( this . topology && this . topology . isConnected ( ) ) {
466
+ return this ;
467
+ }
457
468
458
- if ( typeof options . srvHost === 'string' ) {
459
- const hosts = await resolveSRVRecord ( options ) ;
469
+ const options = this [ kOptions ] ;
460
470
461
- for ( const [ index , host ] of hosts . entries ( ) ) {
462
- options . hosts [ index ] = host ;
463
- }
471
+ if ( typeof options . srvHost === 'string' ) {
472
+ const hosts = await resolveSRVRecord ( options ) ;
473
+
474
+ for ( const [ index , host ] of hosts . entries ( ) ) {
475
+ options . hosts [ index ] = host ;
464
476
}
477
+ }
465
478
466
- const topology = new Topology ( options . hosts , options ) ;
467
- // Events can be emitted before initialization is complete so we have to
468
- // save the reference to the topology on the client ASAP if the event handlers need to access it
469
- this . topology = topology ;
470
- topology . client = this ;
479
+ const topology = new Topology ( options . hosts , options ) ;
480
+ // Events can be emitted before initialization is complete so we have to
481
+ // save the reference to the topology on the client ASAP if the event handlers need to access it
482
+ this . topology = topology ;
483
+ topology . client = this ;
471
484
472
- topology . once ( Topology . OPEN , ( ) => this . emit ( 'open' , this ) ) ;
485
+ topology . once ( Topology . OPEN , ( ) => this . emit ( 'open' , this ) ) ;
473
486
474
- for ( const event of MONGO_CLIENT_EVENTS ) {
475
- topology . on ( event , ( ...args : any [ ] ) : unknown => this . emit ( event , ...( args as any ) ) ) ;
476
- }
487
+ for ( const event of MONGO_CLIENT_EVENTS ) {
488
+ topology . on ( event , ( ...args : any [ ] ) : unknown => this . emit ( event , ...( args as any ) ) ) ;
489
+ }
477
490
478
- const topologyConnect = async ( ) => {
479
- try {
480
- await promisify ( callback => topology . connect ( options , callback ) ) ( ) ;
481
- } catch ( error ) {
482
- topology . close ( { force : true } ) ;
483
- throw error ;
484
- }
485
- } ;
486
-
487
- if ( this . autoEncrypter ) {
488
- const initAutoEncrypter = promisify ( callback => this . autoEncrypter ?. init ( callback ) ) ;
489
- await initAutoEncrypter ( ) ;
490
- await topologyConnect ( ) ;
491
- await options . encrypter . connectInternalClient ( ) ;
492
- } else {
493
- await topologyConnect ( ) ;
491
+ const topologyConnect = async ( ) => {
492
+ try {
493
+ await promisify ( callback => topology . connect ( options , callback ) ) ( ) ;
494
+ } catch ( error ) {
495
+ topology . close ( { force : true } ) ;
496
+ throw error ;
494
497
}
498
+ } ;
495
499
496
- return this ;
497
- } , callback ) ;
498
- }
500
+ if ( this . autoEncrypter ) {
501
+ const initAutoEncrypter = promisify ( callback => this . autoEncrypter ?. init ( callback ) ) ;
502
+ await initAutoEncrypter ( ) ;
503
+ await topologyConnect ( ) ;
504
+ await options . encrypter . connectInternalClient ( ) ;
505
+ } else {
506
+ await topologyConnect ( ) ;
507
+ }
499
508
509
+ return this ;
510
+ }
500
511
/**
501
512
* Close the db and its underlying connections
502
513
*
0 commit comments