Question

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.

Was it helpful?

Solution

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.

OTHER TIPS

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top