diff --git a/lib/connection.js b/lib/connection.js index b0ceb77029b..9c75df9739e 100644 --- a/lib/connection.js +++ b/lib/connection.js @@ -818,32 +818,41 @@ Connection.prototype.dropCollection = async function dropCollection(collection) /** * Waits for connection to be established, so the connection has a `client` * + * @param {Boolean} [noTimeout=false] if set, don't put a timeout on the operation. Used internally so `mongoose.model()` doesn't leave open handles. * @return Promise * @api private */ -Connection.prototype._waitForConnect = async function _waitForConnect() { +Connection.prototype._waitForConnect = async function _waitForConnect(noTimeout) { if ((this.readyState === STATES.connecting || this.readyState === STATES.disconnected) && this._shouldBufferCommands()) { const bufferTimeoutMS = this._getBufferTimeoutMS(); let timeout = null; let timedOut = false; // The element that this function pushes onto `_queue`, stored to make it easy to remove later const queueElement = {}; - await Promise.race([ - new Promise(resolve => { - queueElement.fn = resolve; - this._queue.push(queueElement); - }), - new Promise(resolve => { - timeout = setTimeout( - () => { - timedOut = true; - resolve(); - }, - bufferTimeoutMS - ); - }) - ]); + + // Mongoose executes all elements in `_queue` when initial connection succeeds in `onOpen()`. + const waitForConnectPromise = new Promise(resolve => { + queueElement.fn = resolve; + this._queue.push(queueElement); + }); + + if (noTimeout) { + await waitForConnectPromise; + } else { + await Promise.race([ + waitForConnectPromise, + new Promise(resolve => { + timeout = setTimeout( + () => { + timedOut = true; + resolve(); + }, + bufferTimeoutMS + ); + }) + ]); + } if (timedOut) { const index = this._queue.indexOf(queueElement); diff --git a/lib/model.js b/lib/model.js index aacf6512c17..5d67822865e 100644 --- a/lib/model.js +++ b/lib/model.js @@ -1112,7 +1112,7 @@ Model.init = function init() { ); if (autoCreate == null) { // `autoCreate` may later be set when the connection is opened, so wait for connect before checking - await conn._waitForConnect(); + await conn._waitForConnect(true); autoCreate = utils.getOption( 'autoCreate', this.schema.options,