Reputation: 150263
My ex boss had a weird bug where when he used setInterval
with a long delay interval:
setInterval(func, 3000000 /*50 minutes*/);
Node.js crashed.
func
can be even a simple function that simply console.log('something')
.
Someone suggested him to wrap an anonymous function around func
, and it actually solved his issue.
As much as I know, it shouldn't make a difference and even considered to be a bad practice at least in browsers' javascript.
Is there a difference in Node.js between
setInterval(func, delay)
setInterval(function(){func()}, delay)
or is it a bug in Node.js?
UPDATE:
Upvotes: 9
Views: 446
Reputation: 2814
To address your question directly: Yes, there is a difference. Not in the functionality of setInterval
, but in the scope the function will have when it's run.
Scenario 1:
setInterval(function() {
console.trace();
}, 3000000);
Every 50 minutes, a stack trace will be printed to console. In this case because the function console.trace has been called directly it will maintain the context of console
.
Scenario 2:
setInterval(console.trace, 3000000);
This will throw an error because it will be invoked with the context of the scope that executes it, not console
. To maintain context, you can pass a bound copy of the function:
setInterval(console.trace.bind(console), 3000000);
It doesn't seem the problem your boss had can be reproduced today. So, as others have suggested, it may be a problem with garbage collection. However, I would be more inclined to believe that the function your boss was calling depended on a specific context that was maintained via anonymous function but lost when passing an unbound function.
Upvotes: 1
Reputation: 1669
It's possible that V8 is doing garbage collection behind-the-scenes by removing whatever function you're referencing here as "func". This would leave "func" pointing to an invalid function.
Try running node with the following argument:
node --expose-gc app.js
...and then in your code after the setInterval(func, 10000) call:
global.gc();
...which will trigger the garbage collection in V8. Since I've dropped the timer down to ten seconds you can test the theory without waiting an entire hour.
It's entirely possible that wrapping an anonymous function call then prevents garbage collection from removing your actual function from memory.
Note that you can also start with:
node --trace-gc app.js
...which will log garbage collection by V8. It might tell you something interesting. See https://groups.google.com/forum/#!topic/nodejs/gITsLR7Zkew
Upvotes: 0