From f2b6534d0a24e991f394dcecc8694b99d6faadf2 Mon Sep 17 00:00:00 2001 From: Calvin Montgomery Date: Sat, 13 Jul 2013 22:19:47 -0400 Subject: [PATCH] Fix channels not unloading / video skipping --- acp.js | 16 +++++++++++----- api.js | 16 +++++++++------- channel.js | 1 + playlist.js | 21 +++++++++------------ server.js | 35 +++++++++++++++++++++++++++++------ user.js | 10 +--------- www/channel.html | 12 ++++++++++++ 7 files changed, 72 insertions(+), 39 deletions(-) diff --git a/acp.js b/acp.js index a639d8a8..3faee08b 100644 --- a/acp.js +++ b/acp.js @@ -116,8 +116,9 @@ module.exports = { user.socket.on("acp-list-loaded", function() { var chans = []; - for(var c in Server.channels) { - var chan = Server.channels[c]; + var all = Server.getAllChannels(); + for(var c in all) { + var chan = all[c]; if(!chan) continue; @@ -135,8 +136,8 @@ module.exports = { }); user.socket.on("acp-channel-unload", function(data) { - if(data.name in Server.channels) { - var c = Server.channels[data.name]; + if(Server.getChannel(data.name) !== undefined) { + var c = Server.getChannel(data.name); if(!c) return; ActionLog.record(user.ip, user.name, "acp-channel-unload"); @@ -144,7 +145,12 @@ module.exports = { c.users.forEach(function(u) { c.kick(u, "Channel shutting down"); }); - Server.unload(c); + + // At this point c should be unloaded + // if it's still loaded, kill it + c = Server.getChannel(data.name); + if(c !== undefined) + Server.unload(c); } }); diff --git a/api.js b/api.js index ff2f8999..d4599499 100644 --- a/api.js +++ b/api.js @@ -131,11 +131,11 @@ function handleChannelData(params, req, res) { } var d = { name: cname, - loaded: (cname in Server.channels) + loaded: Server.getChannel(cname) !== undefined }; if(d.loaded) { - var chan = Server.channels[cname]; + var chan = Server.getChannel(cname); d.pagetitle = chan.opts.pagetitle; d.media = chan.playlist.current ? chan.playlist.current.media.pack() : {}; d.usercount = chan.users.length; @@ -158,9 +158,10 @@ function handleChannelData(params, req, res) { function handleChannelList(params, req, res) { if(params.filter == "public") { + var all = Server.getAllChannels(); var clist = []; - for(var key in Server.channels) { - if(Server.channels[key].opts.show_public) { + for(var key in all) { + if(all[key].opts.show_public) { clist.push(key); } } @@ -175,7 +176,7 @@ function handleChannelList(params, req, res) { return; } var clist = []; - for(var key in Server.channels) { + for(var key in Server.getAllChannels()) { clist.push(key); } handleChannelData({channel: clist.join(",")}, req, res); @@ -385,8 +386,9 @@ function handleProfileChange(params, req, res) { error: result ? "" : "Internal error. Contact an administrator" }); - for(var n in Server.channels) { - var chan = Server.channels[n]; + var all = Server.getAllChannels(); + for(var n in all) { + var chan = all[n]; for(var i = 0; i < chan.users.length; i++) { if(chan.users[i].name.toLowerCase() == name) { chan.users[i].profile = { diff --git a/channel.js b/channel.js index dfa10e93..b11b85f7 100644 --- a/channel.js +++ b/channel.js @@ -650,6 +650,7 @@ Channel.prototype.userLeave = function(user) { this.logger.log("--- /" + user.ip + " (" + user.name + ") left"); if(this.users.length == 0) { this.logger.log("*** Channel empty, unloading"); + var name = this.name; Server.unload(this); } } diff --git a/playlist.js b/playlist.js index cb56fa36..3dee6bee 100644 --- a/playlist.js +++ b/playlist.js @@ -12,6 +12,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI ULList = require("./ullist").ULList; var Media = require("./media").Media; var InfoGetter = require("./get-info"); +var AllPlaylists = {}; function PlaylistItem(media, uid) { this.media = media; @@ -32,6 +33,11 @@ PlaylistItem.prototype.pack = function() { } function Playlist(chan) { + if(chan.name in AllPlaylists && AllPlaylists[chan.name]) { + var pl = AllPlaylists[chan.name]; + if("_leadInterval" in pl) + pl.die(); + } this.items = new ULList(); this.current = null; this.next_uid = 0; @@ -47,31 +53,20 @@ function Playlist(chan) { this.lock = false; this.action_queue = []; this._qaInterval = false; + AllPlaylists[chan.name] = this; if(chan) { this.channel = chan; var pl = this; this.on("mediaUpdate", function(m) { - if(chan != pl.channel) { - pl.die(); - return; - } chan.sendAll("mediaUpdate", m.timeupdate()); }); this.on("changeMedia", function(m) { - if(chan != pl.channel) { - pl.die(); - return; - } chan.onVideoChange(); chan.sendAll("setCurrent", pl.current.uid); chan.sendAll("changeMedia", m.fullupdate()); }); this.on("remove", function(item) { - if(chan != pl.channel) { - pl.die(); - return; - } chan.broadcastPlaylistMeta(); chan.sendAll("delete", { uid: item.uid @@ -129,6 +124,8 @@ Playlist.prototype.die = function () { clearInterval(this._leadInterval); this._leadInterval = false; } + for(var key in this) + delete this[key]; } Playlist.prototype.load = function(data, callback) { diff --git a/server.js b/server.js index 07bc03a4..d1c2c688 100644 --- a/server.js +++ b/server.js @@ -106,7 +106,7 @@ var Database = require("./database.js"); Database.setup(Config); Database.init(); -exports.channels = {}; +var channels = {}; exports.clients = {}; fs.exists("chandump", function(exists) { @@ -181,19 +181,42 @@ if(!Config.DEBUG) { function shutdown() { Logger.syslog.log("Unloading channels..."); - for(var name in exports.channels) { - if(exports.channels[name].registered) - exports.channels[name].saveDump(); + for(var name in channels) { + if(channels[name].registered) + channels[name].saveDump(); } Logger.syslog.log("Shutting Down"); process.exit(0); } +exports.getChannel = function (name) { + return channels[name]; +} + +exports.getAllChannels = function () { + return channels; +} + +var Channel = require("./channel.js").Channel; +exports.createChannel = function (name) { + var chan = new Channel(name); + channels[name] = chan; + return chan; +} + +exports.getOrCreateChannel = function (name) { + var chan = exports.getChannel(name); + if(chan !== undefined) + return chan; + return exports.createChannel(name); +} + exports.unload = function(chan) { if(chan.registered) { chan.saveDump(); } chan.playlist.die(); - exports.channels[chan.name] = null; - delete exports.channels[chan.name]; + delete channels[chan.name]; + for(var i in chan) + delete chan[i]; } diff --git a/user.js b/user.js index e5378d34..4a261511 100644 --- a/user.js +++ b/user.js @@ -97,15 +97,7 @@ User.prototype.initCallbacks = function() { if(data.name.length > 100) return; data.name = data.name.toLowerCase(); - // Channel already loaded - if(data.name in Server.channels && Server.channels[data.name] != null) { - this.channel = Server.channels[data.name]; - } - // Channel not loaded - else { - Server.channels[data.name] = new Channel(data.name); - this.channel = Server.channels[data.name]; - } + this.channel = Server.getOrCreateChannel(data.name); if(this.loggedIn) { var chanrank = this.channel.getRank(this.name); if(chanrank > this.rank) { diff --git a/www/channel.html b/www/channel.html index dc69c0f2..8215d0f1 100644 --- a/www/channel.html +++ b/www/channel.html @@ -211,6 +211,18 @@
+ + +