I'm reloading a module this way:
require('./module.js'); // require the module
delete require.cache('/module.js'); // delete module from cache
require('/module.js'); // re-require the module
But there is a problem if the module contains something like this:
setInterval(function(){
console.log('hello!');
}, 1000);
Every time I reload the module a new setInterval is called, but the last one is NOT closed.
Is there any way to know about each module's (long) running functions so I can stop them before I require it again? Or any suggestions how can I make this work?
I'm open to any crazy ideas.
This is just a wild guess but you may be able to load the module within a domain.
When you are done use domain.dispose() to clear the timers:
The dispose method destroys a domain, and makes a best effort attempt to clean up any and all IO that is associated with the domain. Streams are aborted, ended, closed, and/or destroyed. Timers are cleared. Explicitly bound callbacks are no longer called. Any error events that are raised as a result of this are ignored.
I would simply set a reference to the interval and expose a method in order to stop it like:
var interval = setInterval(function () {
console.log('hello');
}, 1000);
var clearInt = clearInterval(interval);
I dont think you can hook into any events as you are simply deleting a reference. If it doesnt exist anymore it reloads. Before you do this call the clearInt function.
You could create an IntervalRegistry in your main application:
global.IntervalRegistry = {
intervals : {},
register : function(module, id) {
if (! this.intervals[module])
{
this.intervals[module] = [];
}
this.intervals[module].push(id);
},
clean : function(module) {
for (var i in this.intervals[module])
{
var id = this.intervals[module][i];
clearInterval(id);
}
delete this.intervals[module];
}
};
In your module, you would register the interval created there:
// module.js
IntervalRegistry.register(__filename, setInterval(function() {
console.log('hello!');
}, 1000));
When it's time to clean up, call this:
var modulename = '/full/path/to/module.js'; // !!! see below
IntervalRegistry.clean(modulename);
delete require.cache[modulename];
Remember that modules are stored with their full filename in require.cache.