Skip to content

Commit f1c6ad2

Browse files
authored
Merge pull request #15251 from Automattic/vkarpov15/gh-15241-2
fix(model): avoid adding timeout on `Model.init()` buffering to avoid unintentional dangling open handles
2 parents b80a8d9 + 0a2da71 commit f1c6ad2

File tree

2 files changed

+26
-17
lines changed

2 files changed

+26
-17
lines changed

lib/connection.js

Lines changed: 25 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -818,32 +818,41 @@ Connection.prototype.dropCollection = async function dropCollection(collection)
818818
/**
819819
* Waits for connection to be established, so the connection has a `client`
820820
*
821+
* @param {Boolean} [noTimeout=false] if set, don't put a timeout on the operation. Used internally so `mongoose.model()` doesn't leave open handles.
821822
* @return Promise
822823
* @api private
823824
*/
824825

825-
Connection.prototype._waitForConnect = async function _waitForConnect() {
826+
Connection.prototype._waitForConnect = async function _waitForConnect(noTimeout) {
826827
if ((this.readyState === STATES.connecting || this.readyState === STATES.disconnected) && this._shouldBufferCommands()) {
827828
const bufferTimeoutMS = this._getBufferTimeoutMS();
828829
let timeout = null;
829830
let timedOut = false;
830831
// The element that this function pushes onto `_queue`, stored to make it easy to remove later
831832
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-
]);
833+
834+
// Mongoose executes all elements in `_queue` when initial connection succeeds in `onOpen()`.
835+
const waitForConnectPromise = new Promise(resolve => {
836+
queueElement.fn = resolve;
837+
this._queue.push(queueElement);
838+
});
839+
840+
if (noTimeout) {
841+
await waitForConnectPromise;
842+
} else {
843+
await Promise.race([
844+
waitForConnectPromise,
845+
new Promise(resolve => {
846+
timeout = setTimeout(
847+
() => {
848+
timedOut = true;
849+
resolve();
850+
},
851+
bufferTimeoutMS
852+
);
853+
})
854+
]);
855+
}
847856

848857
if (timedOut) {
849858
const index = this._queue.indexOf(queueElement);

lib/model.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1112,7 +1112,7 @@ Model.init = function init() {
11121112
);
11131113
if (autoCreate == null) {
11141114
// `autoCreate` may later be set when the connection is opened, so wait for connect before checking
1115-
await conn._waitForConnect();
1115+
await conn._waitForConnect(true);
11161116
autoCreate = utils.getOption(
11171117
'autoCreate',
11181118
this.schema.options,

0 commit comments

Comments
 (0)