@@ -318,6 +318,8 @@ export class MongoClient extends TypedEventEmitter<MongoClientEvents> {
318
318
topology ?: Topology ;
319
319
/** @internal */
320
320
readonly mongoLogger : MongoLogger ;
321
+ /** @internal */
322
+ private connectionLock ?: Promise < this> ;
321
323
322
324
/**
323
325
* The consolidate, parsed, transformed and merged options.
@@ -409,46 +411,57 @@ export class MongoClient extends TypedEventEmitter<MongoClientEvents> {
409
411
return this ;
410
412
}
411
413
412
- const options = this [ kOptions ] ;
414
+ if ( this . connectionLock ) {
415
+ return this . connectionLock ;
416
+ }
417
+
418
+ this . connectionLock = ( async ( ) => {
419
+ const options = this [ kOptions ] ;
413
420
414
- if ( typeof options . srvHost === 'string' ) {
415
- const hosts = await resolveSRVRecord ( options ) ;
421
+ if ( typeof options . srvHost === 'string' ) {
422
+ const hosts = await resolveSRVRecord ( options ) ;
416
423
417
- for ( const [ index , host ] of hosts . entries ( ) ) {
418
- options . hosts [ index ] = host ;
424
+ for ( const [ index , host ] of hosts . entries ( ) ) {
425
+ options . hosts [ index ] = host ;
426
+ }
419
427
}
420
- }
421
428
422
- const topology = new Topology ( options . hosts , options ) ;
423
- // Events can be emitted before initialization is complete so we have to
424
- // save the reference to the topology on the client ASAP if the event handlers need to access it
425
- this . topology = topology ;
426
- topology . client = this ;
429
+ const topology = new Topology ( options . hosts , options ) ;
430
+ // Events can be emitted before initialization is complete so we have to
431
+ // save the reference to the topology on the client ASAP if the event handlers need to access it
432
+ this . topology = topology ;
433
+ topology . client = this ;
427
434
428
- topology . once ( Topology . OPEN , ( ) => this . emit ( 'open' , this ) ) ;
435
+ topology . once ( Topology . OPEN , ( ) => this . emit ( 'open' , this ) ) ;
429
436
430
- for ( const event of MONGO_CLIENT_EVENTS ) {
431
- topology . on ( event , ( ...args : any [ ] ) => this . emit ( event , ...( args as any ) ) ) ;
432
- }
437
+ for ( const event of MONGO_CLIENT_EVENTS ) {
438
+ topology . on ( event , ( ...args : any [ ] ) => this . emit ( event , ...( args as any ) ) ) ;
439
+ }
433
440
434
- const topologyConnect = async ( ) => {
435
- try {
436
- await promisify ( callback => topology . connect ( options , callback ) ) ( ) ;
437
- } catch ( error ) {
438
- topology . close ( { force : true } ) ;
439
- throw error ;
441
+ const topologyConnect = async ( ) => {
442
+ try {
443
+ await promisify ( callback => topology . connect ( options , callback ) ) ( ) ;
444
+ } catch ( error ) {
445
+ topology . close ( { force : true } ) ;
446
+ throw error ;
447
+ }
448
+ } ;
449
+
450
+ if ( this . autoEncrypter ) {
451
+ const initAutoEncrypter = promisify ( callback => this . autoEncrypter ?. init ( callback ) ) ;
452
+ await initAutoEncrypter ( ) ;
453
+ await topologyConnect ( ) ;
454
+ await options . encrypter . connectInternalClient ( ) ;
455
+ } else {
456
+ await topologyConnect ( ) ;
440
457
}
441
- } ;
442
458
443
- if ( this . autoEncrypter ) {
444
- const initAutoEncrypter = promisify ( callback => this . autoEncrypter ?. init ( callback ) ) ;
445
- await initAutoEncrypter ( ) ;
446
- await topologyConnect ( ) ;
447
- await options . encrypter . connectInternalClient ( ) ;
448
- } else {
449
- await topologyConnect ( ) ;
450
- }
459
+ return this ;
460
+ } ) ( ) ;
451
461
462
+ await this . connectionLock ;
463
+ // release
464
+ this . connectionLock = undefined ;
452
465
return this ;
453
466
}
454
467
0 commit comments