@@ -824,10 +824,54 @@ Connection.prototype.dropCollection = async function dropCollection(collection)
824824
825825Connection . prototype . _waitForConnect = async function _waitForConnect ( ) {
826826 if ( ( this . readyState === STATES . connecting || this . readyState === STATES . disconnected ) && this . _shouldBufferCommands ( ) ) {
827- await new Promise ( resolve => {
828- this . _queue . push ( { fn : resolve } ) ;
829- } ) ;
827+ const bufferTimeoutMS = this . _getBufferTimeoutMS ( ) ;
828+ let timeout = null ;
829+ let timedOut = false ;
830+ // The element that this function pushes onto `_queue`, stored to make it easy to remove later
831+ const queueElement = { } ;
832+ await Promise . race ( [
833+ new Promise ( resolve => {
834+ queueElement . fn = resolve ;
835+ this . _queue . push ( queueElement ) ;
836+ } ) ,
837+ new Promise ( resolve => {
838+ timeout = setTimeout (
839+ ( ) => {
840+ timedOut = true ;
841+ resolve ( ) ;
842+ } ,
843+ bufferTimeoutMS
844+ ) ;
845+ } )
846+ ] ) ;
847+
848+ if ( timedOut ) {
849+ const index = this . _queue . indexOf ( queueElement ) ;
850+ if ( index !== - 1 ) {
851+ this . _queue . splice ( index , 1 ) ;
852+ }
853+ const message = 'Connection operation buffering timed out after ' + bufferTimeoutMS + 'ms' ;
854+ throw new MongooseError ( message ) ;
855+ } else if ( timeout != null ) {
856+ // Not strictly necessary, but avoid the extra overhead of creating a new MongooseError
857+ // in case of success
858+ clearTimeout ( timeout ) ;
859+ }
860+ }
861+ } ;
862+
863+ /*!
864+ * Get the default buffer timeout for this connection
865+ */
866+
867+ Connection . prototype . _getBufferTimeoutMS = function _getBufferTimeoutMS ( ) {
868+ if ( this . config . bufferTimeoutMS != null ) {
869+ return this . config . bufferTimeoutMS ;
830870 }
871+ if ( this . base != null && this . base . get ( 'bufferTimeoutMS' ) != null ) {
872+ return this . base . get ( 'bufferTimeoutMS' ) ;
873+ }
874+ return 10000 ;
831875} ;
832876
833877/**
@@ -1156,6 +1200,10 @@ Connection.prototype.close = async function close(force) {
11561200 this . $wasForceClosed = ! ! force ;
11571201 }
11581202
1203+ if ( this . _lastHeartbeatAt != null ) {
1204+ this . _lastHeartbeatAt = null ;
1205+ }
1206+
11591207 for ( const model of Object . values ( this . models ) ) {
11601208 // If manually disconnecting, make sure to clear each model's `$init`
11611209 // promise, so Mongoose knows to re-run `init()` in case the
0 commit comments