seeking help from nodejs gurus out there on usage of promises. I have the following test program, in which I invoke an async "q" function that simply throws an exception. This program leaks memory pretty consistently; but the leak goes away if uncomment the .done() call.
Why does the leak happen when the promise is unterminated (i.e. no done() call)? I tried to follow the documentation, but have trouble understanding the explanation of the done() method. Thanks in advance for your help!
Here's my code:
(function() {
var MAX_ITER_COUNT, Q, iterCount, maxMem, noop, qDoit, test;
Q = require("q");
iterCount = 0;
MAX_ITER_COUNT = 10 * 1000;
maxMem = 0;
noop = function() {};
qDoit = function() {
var currentMem;
currentMem = Math.round(process.memoryUsage().heapUsed / 1024 / 1024);
if (currentMem > maxMem) {
maxMem = currentMem;
}
console.log("" + iterCount + " - memory is: " + currentMem + "/" + maxMem + " MB");
return Q(10).then(function() {
throw new Error("X");
});
};
test = function() {
if (iterCount++ > MAX_ITER_COUNT) {
console.log("DONE");
return;
}
// ---- If I uncomment the done() call below the leak goes away ----
return qDoit()["finally"](function() {
return setImmediate(test);
})
//.done(noop, noop, noop);
};
Q.onerror = function() {};
test();
}).call(this);
Answering my own question, hopefully it will help someone.
On digging a bit into the q
library code, it looks like all unhandled exceptions are put in an array called unhandledRejections
, by default. Not sure why it was implemented like this, but presumably to help developers track down un-handled exceptions. This behavior can be changed by calling Q.stopUnhandledRejectionTracking()
. When I did this, the memory leak went away, even without the .done()
call.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With