Skip to content

Commit

Permalink
Improve ratelimit handling
Browse files Browse the repository at this point in the history
* Exception for DELETE messages > 2 weeks old
* Exception for PUT/DELETE reactions
* Cleanup latency calculations

Co-authored-by: bsian03 <[email protected]>
  • Loading branch information
abalabahaha and bsian03 committed Apr 25, 2021
1 parent 3e86cd7 commit d58b788
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 13 deletions.
34 changes: 23 additions & 11 deletions lib/rest/RequestHandler.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,8 @@ class RequestHandler {
this.userAgent = `DiscordBot (https://github.com/abalabahaha/eris, ${require("../../package.json").version})`;
this.ratelimits = {};
this.latencyRef = {
latency: 500,
offset: this.options.ratelimiterOffset,
raw: new Array(10).fill(500),
latency: this.options.ratelimiterOffset,
raw: new Array(10).fill(this.options.ratelimiterOffset),
timeOffset: 0,
timeOffsets: new Array(10).fill(0),
lastTimeOffsetCheck: 0
Expand Down Expand Up @@ -191,8 +190,10 @@ class RequestHandler {

req.once("response", (resp) => {
latency = Date.now() - latency;
this.latencyRef.raw.push(latency);
this.latencyRef.latency = this.latencyRef.latency - ~~(this.latencyRef.raw.shift() / 10) + ~~(latency / 10);
if(!this.options.disableLatencyCompensation) {
this.latencyRef.raw.push(latency);
this.latencyRef.latency = this.latencyRef.latency - ~~(this.latencyRef.raw.shift() / 10) + ~~(latency / 10);
}

if(this._client.listeners("rawREST").length) {
/**
Expand Down Expand Up @@ -283,11 +284,11 @@ class RequestHandler {
this.ratelimits[route].reset = (retryAfter || 1) + now;
}
} else if(resp.headers["x-ratelimit-reset"]) {
if((~route.lastIndexOf("/reactions/:id")) && (+resp.headers["x-ratelimit-reset"] * 1000 - headerNow) === 1000) {
this.ratelimits[route].reset = now + 250;
} else {
this.ratelimits[route].reset = Math.max(+resp.headers["x-ratelimit-reset"] * 1000 - (this.options.disableLatencyCompensation ? 0 : this.latencyRef.timeOffset), now);
let resetTime = +resp.headers["x-ratelimit-reset"] * 1000;
if(route.endsWith("/reactions/:id") && (+resp.headers["x-ratelimit-reset"] * 1000 - headerNow) === 1000) {
resetTime = now + 250;
}
this.ratelimits[route].reset = Math.max(resetTime - this.latencyRef.latency, now);
} else {
this.ratelimits[route].reset = now;
}
Expand Down Expand Up @@ -397,10 +398,21 @@ class RequestHandler {
routefy(url, method) {
let route = url.replace(/\/([a-z-]+)\/(?:[0-9]{17,19})/g, function(match, p) {
return p === "channels" || p === "guilds" || p === "webhooks" ? match : `/${p}/:id`;
}).replace(/\/reactions\/[^/]+/g, "/reactions/:id").replace(/^\/webhooks\/(\d+)\/[A-Za-z0-9-_]{64,}/, "/webhooks/$1/:token");
if(method === "DELETE" && route.endsWith("/messages/:id")) { // Delete Messsage endpoint has its own ratelimit
}).replace(/\/reactions\/[^/]+/g, "/reactions/:id").replace(/\/reactions\/:id\/[^/]+/g, "/reactions/:id/:userID").replace(/^\/webhooks\/(\d+)\/[A-Za-z0-9-_]{64,}/, "/webhooks/$1/:token");
if(method === "DELETE" && route.endsWith("/messages/:id")) {
const messageID = url.slice(url.lastIndexOf("/") + 1);
const createdAt = Base.getCreatedAt(messageID);
if(Date.now() - this.latencyRef.latency - createdAt >= 1000 * 60 * 60 * 24 * 14) {
method += "_OLD";
}
route = method + route;
}
if(method === "PUT" || method === "DELETE") {
let index = route.indexOf("/reactions");
if(index !== -1) {
route = "MODIFY" + route.slice(0, index + 10);
}
}
return route;
}

Expand Down
6 changes: 5 additions & 1 deletion lib/structures/Base.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ class Base {
}

get createdAt() {
return Math.floor(this.id / 4194304) + 1420070400000;
return Base.getCreatedAt(this.id);
}

[util.inspect.custom]() {
Expand Down Expand Up @@ -53,6 +53,10 @@ class Base {
}
return json;
}

static getCreatedAt(id) {
return Math.floor(id / 4194304) + 1420070400000;
}
}

module.exports = Base;
2 changes: 1 addition & 1 deletion lib/util/SequentialBucket.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ class SequentialBucket {
return;
}
const now = Date.now();
const offset = this.latencyRef.latency + (this.latencyRef.offset || 0);
const offset = this.latencyRef.latency;
if(!this.reset || this.reset < now - offset) {
this.reset = now - offset;
this.remaining = this.limit;
Expand Down

0 comments on commit d58b788

Please sign in to comment.