From e072c5846018a7ad509a4abe5808421cf734fe46 Mon Sep 17 00:00:00 2001 From: Amish Shah Date: Sun, 6 Dec 2015 19:02:10 +0000 Subject: [PATCH] added interval fixes - bots die gracefully now --- lib/Client/InternalClient.js | 133 +++++++++++++++++++++-------------- lib/Voice/VoiceConnection.js | 3 +- src/Client/InternalClient.js | 30 +++++--- src/Voice/VoiceConnection.js | 3 +- test/msgbot.js | 5 ++ 5 files changed, 109 insertions(+), 65 deletions(-) diff --git a/lib/Client/InternalClient.js b/lib/Client/InternalClient.js index 5b8b47ad3..e7606e280 100644 --- a/lib/Client/InternalClient.js +++ b/lib/Client/InternalClient.js @@ -138,14 +138,40 @@ var InternalClient = (function () { this.channels = new _UtilCache2["default"](); this.servers = new _UtilCache2["default"](); this.private_channels = new _UtilCache2["default"](); - this.typingIntervals = []; + + this.intervals = { + typing: [], + kai: null, + misc: [] + }; + this.voiceConnection = null; this.resolver = new _ResolverResolver2["default"](this); this.readyTime = null; - this.messageAwaits = {}; } + InternalClient.prototype.cleanIntervals = function cleanIntervals() { + for (var _iterator = this.intervals.typing.concat(this.intervals.misc).concat(this.intervals.kai), _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) { + var _ref; + + if (_isArray) { + if (_i >= _iterator.length) break; + _ref = _iterator[_i++]; + } else { + _i = _iterator.next(); + if (_i.done) break; + _ref = _i.value; + } + + var interval = _ref; + + if (interval) { + clearInterval(interval); + } + } + }; + //def leaveVoiceChannel InternalClient.prototype.leaveVoiceChannel = function leaveVoiceChannel() { @@ -276,19 +302,19 @@ var InternalClient = (function () { return _superagent2["default"].del(_Constants.Endpoints.SERVER(server.id)).set("authorization", this.token).end().then(function () { // remove channels of server then the server - for (var _iterator = server.channels, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) { - var _ref; + for (var _iterator2 = server.channels, _isArray2 = Array.isArray(_iterator2), _i2 = 0, _iterator2 = _isArray2 ? _iterator2 : _iterator2[Symbol.iterator]();;) { + var _ref2; - if (_isArray) { - if (_i >= _iterator.length) break; - _ref = _iterator[_i++]; + if (_isArray2) { + if (_i2 >= _iterator2.length) break; + _ref2 = _iterator2[_i2++]; } else { - _i = _iterator.next(); - if (_i.done) break; - _ref = _i.value; + _i2 = _iterator2.next(); + if (_i2.done) break; + _ref2 = _i2.value; } - var chan = _ref; + var chan = _ref2; _this6.channels.remove(chan); } @@ -607,19 +633,19 @@ var InternalClient = (function () { if (data.permissions) { newData.permissions = 0; - for (var _iterator2 = data.permissions, _isArray2 = Array.isArray(_iterator2), _i2 = 0, _iterator2 = _isArray2 ? _iterator2 : _iterator2[Symbol.iterator]();;) { - var _ref2; + for (var _iterator3 = data.permissions, _isArray3 = Array.isArray(_iterator3), _i3 = 0, _iterator3 = _isArray3 ? _iterator3 : _iterator3[Symbol.iterator]();;) { + var _ref3; - if (_isArray2) { - if (_i2 >= _iterator2.length) break; - _ref2 = _iterator2[_i2++]; + if (_isArray3) { + if (_i3 >= _iterator3.length) break; + _ref3 = _iterator3[_i3++]; } else { - _i2 = _iterator2.next(); - if (_i2.done) break; - _ref2 = _i2.value; + _i3 = _iterator3.next(); + if (_i3.done) break; + _ref3 = _i3.value; } - var perm = _ref2; + var perm = _ref3; if (perm instanceof String || typeof perm === "string") { newData.permissions |= _Constants.Permissions[perm] || 0; @@ -679,19 +705,19 @@ var InternalClient = (function () { return r.id; }); - for (var _iterator3 = roles, _isArray3 = Array.isArray(_iterator3), _i3 = 0, _iterator3 = _isArray3 ? _iterator3 : _iterator3[Symbol.iterator]();;) { - var _ref3; + for (var _iterator4 = roles, _isArray4 = Array.isArray(_iterator4), _i4 = 0, _iterator4 = _isArray4 ? _iterator4 : _iterator4[Symbol.iterator]();;) { + var _ref4; - if (_isArray3) { - if (_i3 >= _iterator3.length) break; - _ref3 = _iterator3[_i3++]; + if (_isArray4) { + if (_i4 >= _iterator4.length) break; + _ref4 = _iterator4[_i4++]; } else { - _i3 = _iterator3.next(); - if (_i3.done) break; - _ref3 = _i3.value; + _i4 = _iterator4.next(); + if (_i4.done) break; + _ref4 = _i4.value; } - var role = _ref3; + var role = _ref4; if (!role.server.memberMap[member.id]) { return Promise.reject(new Error("member not in server")); @@ -750,19 +776,19 @@ var InternalClient = (function () { return r.id; }); - for (var _iterator4 = roles, _isArray4 = Array.isArray(_iterator4), _i4 = 0, _iterator4 = _isArray4 ? _iterator4 : _iterator4[Symbol.iterator]();;) { - var _ref4; + for (var _iterator5 = roles, _isArray5 = Array.isArray(_iterator5), _i5 = 0, _iterator5 = _isArray5 ? _iterator5 : _iterator5[Symbol.iterator]();;) { + var _ref5; - if (_isArray4) { - if (_i4 >= _iterator4.length) break; - _ref4 = _iterator4[_i4++]; + if (_isArray5) { + if (_i5 >= _iterator5.length) break; + _ref5 = _iterator5[_i5++]; } else { - _i4 = _iterator4.next(); - if (_i4.done) break; - _ref4 = _i4.value; + _i5 = _iterator5.next(); + if (_i5.done) break; + _ref5 = _i5.value; } - var role = _ref4; + var role = _ref5; if (!role.server.memberMap[member.id]) { return Promise.reject(new Error("member not in server")); @@ -925,12 +951,12 @@ var InternalClient = (function () { return this.resolver.resolveChannel(channel).then(function (channel) { - if (_this23.typingIntervals[channel.id]) { + if (_this23.intervals.typing[channel.id]) { // typing interval already exists, leave it alone throw new Error("Already typing in that channel"); } - _this23.typingIntervals[channel.id] = setInterval(function () { + _this23.intervals.typing[channel.id] = setInterval(function () { return _this23.sendTyping(channel)["catch"](function (error) { return _this23.emit("error", error); }); @@ -947,13 +973,13 @@ var InternalClient = (function () { return this.resolver.resolveChannel(channel).then(function (channel) { - if (!_this24.typingIntervals[channel.id]) { + if (!_this24.intervals.typing[channel.id]) { // typing interval doesn't exist throw new Error("Not typing in that channel"); } - clearInterval(_this24.typingIntervals[channel.id]); - _this24.typingIntervals[channel.id] = false; + clearInterval(_this24.intervals.typing[channel.id]); + _this24.intervals.typing[channel.id] = false; }); }; @@ -1112,6 +1138,7 @@ var InternalClient = (function () { self.websocket = null; self.state = _ConnectionState2["default"].DISCONNECTED; client.emit("disconnected"); + self.cleanIntervals(); }; this.websocket.onerror = function (e) { @@ -1147,7 +1174,7 @@ var InternalClient = (function () { }); self.state = _ConnectionState2["default"].READY; - setInterval(function () { + self.intervals.kai = setInterval(function () { return self.sendWS({ op: 1, d: Date.now() }); }, data.heartbeat_interval); @@ -1229,19 +1256,19 @@ var InternalClient = (function () { var server = self.servers.get("id", data.id); if (server) { - for (var _iterator5 = server.channels, _isArray5 = Array.isArray(_iterator5), _i5 = 0, _iterator5 = _isArray5 ? _iterator5 : _iterator5[Symbol.iterator]();;) { - var _ref5; + for (var _iterator6 = server.channels, _isArray6 = Array.isArray(_iterator6), _i6 = 0, _iterator6 = _isArray6 ? _iterator6 : _iterator6[Symbol.iterator]();;) { + var _ref6; - if (_isArray5) { - if (_i5 >= _iterator5.length) break; - _ref5 = _iterator5[_i5++]; + if (_isArray6) { + if (_i6 >= _iterator6.length) break; + _ref6 = _iterator6[_i6++]; } else { - _i5 = _iterator5.next(); - if (_i5.done) break; - _ref5 = _i5.value; + _i6 = _iterator6.next(); + if (_i6.done) break; + _ref6 = _i6.value; } - var channel = _ref5; + var channel = _ref6; self.channels.remove(channel); } diff --git a/lib/Voice/VoiceConnection.js b/lib/Voice/VoiceConnection.js index 96bde9076..03885a07e 100644 --- a/lib/Voice/VoiceConnection.js +++ b/lib/Voice/VoiceConnection.js @@ -334,13 +334,12 @@ var VoiceConnection = (function (_EventEmitter) { case 2: self.vWSData = data.d; - KAI = setInterval(function () { + self.KAI = KAI = self.client.internal.intervals.misc["voiceKAI"] = setInterval(function () { if (vWS && vWS.readyState === _ws2["default"].OPEN) vWS.send(JSON.stringify({ op: 3, d: null })); }, data.d.heartbeat_interval); - self.KAI = KAI; var udpPacket = new Buffer(70); udpPacket.writeUIntBE(data.d.ssrc, 0, 4); diff --git a/src/Client/InternalClient.js b/src/Client/InternalClient.js index edf77ec7e..46fb847a8 100644 --- a/src/Client/InternalClient.js +++ b/src/Client/InternalClient.js @@ -75,14 +75,27 @@ export default class InternalClient { this.channels = new Cache(); this.servers = new Cache(); this.private_channels = new Cache(); - this.typingIntervals = []; + + this.intervals = { + typing : [], + kai : null, + misc : [] + }; + this.voiceConnection = null; this.resolver = new Resolver(this); this.readyTime = null; - this.messageAwaits = {}; } + cleanIntervals(){ + for(let interval of this.intervals.typing.concat(this.intervals.misc).concat(this.intervals.kai)){ + if(interval){ + clearInterval(interval); + } + } + } + get uptime() { return (this.readyTime ? Date.now() - this.readyTime : null); } @@ -830,12 +843,12 @@ export default class InternalClient { return this.resolver.resolveChannel(channel) .then(channel => { - if(this.typingIntervals[channel.id]){ + if(this.intervals.typing[channel.id]){ // typing interval already exists, leave it alone throw new Error("Already typing in that channel"); } - this.typingIntervals[channel.id] = setInterval( + this.intervals.typing[channel.id] = setInterval( () => this.sendTyping(channel) .catch(error => this.emit("error", error)), 4000 @@ -851,13 +864,13 @@ export default class InternalClient { return this.resolver.resolveChannel(channel) .then(channel => { - if(!this.typingIntervals[channel.id]){ + if(!this.intervals.typing[channel.id]){ // typing interval doesn't exist throw new Error("Not typing in that channel"); } - clearInterval(this.typingIntervals[channel.id]); - this.typingIntervals[channel.id] = false; + clearInterval(this.intervals.typing[channel.id]); + this.intervals.typing[channel.id] = false; }); } @@ -1016,6 +1029,7 @@ export default class InternalClient { self.websocket = null; self.state = ConnectionState.DISCONNECTED; client.emit("disconnected"); + self.cleanIntervals(); }; this.websocket.onerror = e => { @@ -1051,7 +1065,7 @@ export default class InternalClient { }); self.state = ConnectionState.READY; - setInterval(() => self.sendWS({ op: 1, d: Date.now() }), data.heartbeat_interval); + self.intervals.kai = setInterval(() => self.sendWS({ op: 1, d: Date.now() }), data.heartbeat_interval); client.emit("ready"); client.emit("debug", `ready packet took ${Date.now() - startTime}ms to process`); diff --git a/src/Voice/VoiceConnection.js b/src/Voice/VoiceConnection.js index ecdc9356a..b3d8d2f40 100644 --- a/src/Voice/VoiceConnection.js +++ b/src/Voice/VoiceConnection.js @@ -302,14 +302,13 @@ export default class VoiceConnection extends EventEmitter { case 2: self.vWSData = data.d; - KAI = setInterval(() => { + self.KAI = KAI = self.client.internal.intervals.misc["voiceKAI"] = setInterval(() => { if (vWS && vWS.readyState === WebSocket.OPEN) vWS.send(JSON.stringify({ op: 3, d: null })); }, data.d.heartbeat_interval); - self.KAI = KAI; var udpPacket = new Buffer(70); udpPacket.writeUIntBE(data.d.ssrc, 0, 4); diff --git a/test/msgbot.js b/test/msgbot.js index a651f66bd..38bf32b00 100644 --- a/test/msgbot.js +++ b/test/msgbot.js @@ -7,6 +7,11 @@ var request = require("superagent"); client.on("ready", () => { console.log("ready"); + + setTimeout(() => { + client.internal.websocket.close(); + }, 3000); + }); client.on("message", msg => {