Skip to content

Commit

Permalink
Rewrite WebSocket internals (#1410)
Browse files Browse the repository at this point in the history
* Start rewriting Manager and Connection

* more stuff

* stuff

* Fix ready bug

* some stuff i forgot

* fix some stuff

* add stupid heartbeat ack like seriously who cares

* woo!

* fix a bug

* rate limit the dumb websocket

* stuff

* hdocs

* Docs

* Remove ClientManager#setupKeepAlive as it is now redundant

* Change Client._pingTimestamp to a getter that fetches the timestamp from the WebSocketConnection

* are you happy now eslint smh

* make gus happy

* Add CloseEvent external doc

* Make sure to emit 'reconnecting' when actually reconnecting

* ffs

* Fix RESUME logic

* Add heartbeat ack debug messages, including latency data

* Dumb stuff for Gus

* thx eslint

* more dumb stuff

* more dumb crap smh gus i h8 u

* moar messages

* fix for using wrong status, causing certain events not to be fired (#1422)
  • Loading branch information
amishshah authored Apr 28, 2017
1 parent 95bcac9 commit 195fcfa
Show file tree
Hide file tree
Showing 13 changed files with 536 additions and 427 deletions.
16 changes: 9 additions & 7 deletions src/client/Client.js
Original file line number Diff line number Diff line change
Expand Up @@ -156,13 +156,6 @@ class Client extends EventEmitter {
*/
this.pings = [];

/**
* Timestamp of the latest ping's start time
* @type {number}
* @private
*/
this._pingTimestamp = 0;

/**
* Timeouts set by {@link Client#setTimeout} that are still active
* @type {Set<Timeout>}
Expand All @@ -182,6 +175,15 @@ class Client extends EventEmitter {
}
}

/**
* Timestamp of the latest ping's start time
* @type {number}
* @private
*/
get _pingTimestamp() {
return this.ws.connection ? this.ws.connection.lastPingTimestamp : 0;
}

/**
* Current status of the client's connection to Discord
* @type {?number}
Expand Down
2 changes: 1 addition & 1 deletion src/client/ClientDataManager.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ class ClientDataManager {
}

get pastReady() {
return this.client.ws.status === Constants.Status.READY;
return this.client.ws.connection.status === Constants.Status.READY;
}

newGuild(data) {
Expand Down
18 changes: 9 additions & 9 deletions src/client/ClientManager.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,14 @@ class ClientManager {
this.heartbeatInterval = null;
}

/**
* The status of the client
* @type {number}
*/
get status() {
return this.connection ? this.connection.status : Constants.Status.IDLE;
}

/**
* Connects the Client to the WebSocket
* @param {string} token The authorization token
Expand Down Expand Up @@ -47,17 +55,9 @@ class ClientManager {
}, reject);
}

/**
* Sets up a keep-alive interval to keep the Client's connection valid
* @param {number} time The interval in milliseconds at which heartbeat packets should be sent
*/
setupKeepAlive(time) {
this.heartbeatInterval = time;
this.client.setInterval(() => this.client.ws.heartbeat(true), time);
}

destroy() {
this.client.ws.destroy();
this.client.rest.destroy();
if (!this.client.user) return Promise.resolve();
if (this.client.user.bot) {
this.client.token = null;
Expand Down
6 changes: 6 additions & 0 deletions src/client/rest/RESTManager.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,12 @@ class RESTManager {
this.globallyRateLimited = false;
}

destroy() {
for (const handlerID in this.handlers) {
this.handlers[handlerID].destroy();
}
}

push(handler, apiRequest) {
return new Promise((resolve, reject) => {
handler.push({
Expand Down
4 changes: 4 additions & 0 deletions src/client/rest/RequestHandlers/RequestHandler.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,10 @@ class RequestHandler {
* Attempts to get this RequestHandler to process its current queue
*/
handle() {} // eslint-disable-line no-empty-function

destroy() {
this.queue = [];
}
}

module.exports = RequestHandler;
59 changes: 31 additions & 28 deletions src/client/rest/RequestHandlers/Sequential.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,39 +48,42 @@ class SequentialRequestHandler extends RequestHandler {
execute(item) {
this.busy = true;
return new Promise(resolve => {
item.request.gen().end((err, res) => {
if (res && res.headers) {
this.requestLimit = Number(res.headers['x-ratelimit-limit']);
this.requestResetTime = Number(res.headers['x-ratelimit-reset']) * 1000;
this.requestRemaining = Number(res.headers['x-ratelimit-remaining']);
this.timeDifference = Date.now() - new Date(res.headers.date).getTime();
}
if (err) {
if (err.status === 429) {
this.queue.unshift(item);
this.restManager.client.setTimeout(() => {
this.globalLimit = false;
resolve();
}, Number(res.headers['retry-after']) + this.restManager.client.options.restTimeOffset);
if (res.headers['x-ratelimit-global']) this.globalLimit = true;
} else {
item.reject(err);
resolve(err);
item.request
.gen()
.on('error', e => item.reject(e))
.end((err, res) => {
if (res && res.headers) {
this.requestLimit = Number(res.headers['x-ratelimit-limit']);
this.requestResetTime = Number(res.headers['x-ratelimit-reset']) * 1000;
this.requestRemaining = Number(res.headers['x-ratelimit-remaining']);
this.timeDifference = Date.now() - new Date(res.headers.date).getTime();
}
} else {
this.globalLimit = false;
const data = res && res.body ? res.body : {};
item.resolve(data);
if (this.requestRemaining === 0) {
this.restManager.client.setTimeout(
if (err) {
if (err.status === 429) {
this.queue.unshift(item);
this.restManager.client.setTimeout(() => {
this.globalLimit = false;
resolve();
}, Number(res.headers['retry-after']) + this.restManager.client.options.restTimeOffset);
if (res.headers['x-ratelimit-global']) this.globalLimit = true;
} else {
item.reject(err);
resolve(err);
}
} else {
this.globalLimit = false;
const data = res && res.body ? res.body : {};
item.resolve(data);
if (this.requestRemaining === 0) {
this.restManager.client.setTimeout(
() => resolve(data),
this.requestResetTime - Date.now() + this.timeDifference + this.restManager.client.options.restTimeOffset
);
} else {
resolve(data);
} else {
resolve(data);
}
}
}
});
});
});
}

Expand Down
Loading

0 comments on commit 195fcfa

Please sign in to comment.