mediarefresher: fix memory leak from dangling timers

This commit is contained in:
calzoneman 2016-01-30 19:42:55 -08:00
parent eba787942c
commit ba54848db5
2 changed files with 32 additions and 1 deletions

View File

@ -44,6 +44,15 @@ MediaRefresherModule.prototype.onPreMediaChange = function (data, cb) {
} }
}; };
MediaRefresherModule.prototype.unload = function () {
try {
clearInterval(this._interval);
this._interval = null;
} catch (error) {
Logger.errlog.log(error.stack);
}
};
MediaRefresherModule.prototype.initGoogleDocs = function (data, cb) { MediaRefresherModule.prototype.initGoogleDocs = function (data, cb) {
var self = this; var self = this;
self.refreshGoogleDocs(data, cb); self.refreshGoogleDocs(data, cb);
@ -66,8 +75,10 @@ MediaRefresherModule.prototype.initVimeo = function (data, cb) {
const self = this; const self = this;
self.channel.refCounter.ref("MediaRefresherModule::initVimeo"); self.channel.refCounter.ref("MediaRefresherModule::initVimeo");
Vimeo.extract(data.id).then(function (direct) { Vimeo.extract(data.id).then(function (direct) {
if (self.dead || self.channel.dead) if (self.dead || self.channel.dead) {
self.unload();
return; return;
}
if (self._media === data) { if (self._media === data) {
data.meta.direct = direct; data.meta.direct = direct;
@ -88,6 +99,7 @@ MediaRefresherModule.prototype.refreshGoogleDocs = function (media, cb) {
var self = this; var self = this;
if (self.dead || self.channel.dead) { if (self.dead || self.channel.dead) {
self.unload();
return; return;
} }
@ -153,6 +165,7 @@ MediaRefresherModule.prototype.initGooglePlus = function (media, cb) {
var self = this; var self = this;
if (self.dead || self.channel.dead) { if (self.dead || self.channel.dead) {
self.unload();
return; return;
} }

View File

@ -195,6 +195,24 @@ Server.prototype.unloadChannel = function (chan) {
chan.notifyModules("unload", []); chan.notifyModules("unload", []);
Object.keys(chan.modules).forEach(function (k) { Object.keys(chan.modules).forEach(function (k) {
chan.modules[k].dead = true; chan.modules[k].dead = true;
/*
* Automatically clean up any timeouts/intervals assigned
* to properties of channel modules. Prevents a memory leak
* in case of forgetting to clear the timer on the "unload"
* module event.
*/
Object.keys(chan.modules[k]).forEach(function (prop) {
if (chan.modules[k][prop] && chan.modules[k][prop]._onTimeout) {
Logger.errlog.log("Warning: detected non-null timer when unloading " +
"module " + k + ": " + prop);
try {
clearTimeout(chan.modules[k][prop]);
clearInterval(chan.modules[k][prop]);
} catch (error) {
Logger.errlog.log(error.stack);
}
}
});
}); });
for (var i = 0; i < this.channels.length; i++) { for (var i = 0; i < this.channels.length; i++) {