From b5f37728a7f5cd07970ee5cbda22ce5c99928265 Mon Sep 17 00:00:00 2001 From: Amish Shah Date: Wed, 2 May 2018 17:57:48 +0100 Subject: [PATCH] feature: allow sweeping of inactive request buckets --- src/client/BaseClient.js | 26 +++++++++++++------------- src/client/Client.js | 3 +++ src/rest/RESTManager.js | 9 +++++++++ src/rest/handlers/RequestHandler.js | 7 +++++++ src/util/Constants.js | 3 +++ 5 files changed, 35 insertions(+), 13 deletions(-) diff --git a/src/client/BaseClient.js b/src/client/BaseClient.js index 0d0e32caf..6e671f99e 100644 --- a/src/client/BaseClient.js +++ b/src/client/BaseClient.js @@ -11,19 +11,6 @@ class BaseClient extends EventEmitter { constructor(options = {}) { super(); - /** - * The options the client was instantiated with - * @type {ClientOptions} - */ - this.options = Util.mergeDefault(DefaultOptions, options); - - /** - * The REST manager of the client - * @type {RESTManager} - * @private - */ - this.rest = new RESTManager(this, options._tokenType); - /** * Timeouts set by {@link BaseClient#setTimeout} that are still active * @type {Set} @@ -37,6 +24,19 @@ class BaseClient extends EventEmitter { * @private */ this._intervals = new Set(); + + /** + * The options the client was instantiated with + * @type {ClientOptions} + */ + this.options = Util.mergeDefault(DefaultOptions, options); + + /** + * The REST manager of the client + * @type {RESTManager} + * @private + */ + this.rest = new RESTManager(this, options._tokenType); } /** diff --git a/src/client/Client.js b/src/client/Client.js index 493cb921f..b3aa6acf6 100644 --- a/src/client/Client.js +++ b/src/client/Client.js @@ -468,6 +468,9 @@ class Client extends BaseClient { if (typeof options.restWsBridgeTimeout !== 'number' || isNaN(options.restWsBridgeTimeout)) { throw new TypeError('CLIENT_INVALID_OPTION', 'restWsBridgeTimeout', 'a number'); } + if (typeof options.restSweepInterval !== 'number' || isNaN(options.restSweepInterval)) { + throw new TypeError('CLIENT_INVALID_OPTION', 'restSweepInterval', 'a number'); + } if (typeof options.internalSharding !== 'boolean') { throw new TypeError('CLIENT_INVALID_OPTION', 'internalSharding', 'a boolean'); } diff --git a/src/rest/RESTManager.js b/src/rest/RESTManager.js index d62423979..8f361447f 100644 --- a/src/rest/RESTManager.js +++ b/src/rest/RESTManager.js @@ -13,6 +13,15 @@ class RESTManager { this.tokenPrefix = tokenPrefix; this.versioned = true; this.timeDifferences = []; + if (client.options.restSweepInterval > 0) { + client.setInterval(() => { + for (const handler in this.handlers) { + if (this.handlers[handler] && this.handlers[handler]._inactive) { + this.handlers[handler] = undefined; + } + } + }, client.options.restSweepInterval * 1000); + } } get api() { diff --git a/src/rest/handlers/RequestHandler.js b/src/rest/handlers/RequestHandler.js index c4226a45c..bf6609029 100644 --- a/src/rest/handlers/RequestHandler.js +++ b/src/rest/handlers/RequestHandler.js @@ -26,6 +26,13 @@ class RequestHandler { this.handle(); } + get _inactive() { + return this.queue.length === 0 && + !this.limited && + Date.now() > this.resetTime && + (typeof this.busy === 'undefined' || this.busy === false); + } + execute(item) { return new Promise((resolve, reject) => { const finish = timeout => { diff --git a/src/util/Constants.js b/src/util/Constants.js index a0cccd73a..65b275a35 100644 --- a/src/util/Constants.js +++ b/src/util/Constants.js @@ -26,6 +26,8 @@ const browser = exports.browser = typeof window !== 'undefined'; * corresponding websocket events * @property {number} [restTimeOffset=500] Extra time in millseconds to wait before continuing to make REST * requests (higher values will reduce rate-limiting errors on bad connections) + * @property {number} [restSweepInterval=60] How frequently to delete inactive request buckets, in seconds + * (or 0 for never) * @property {PresenceData} [presence] Presence data to use upon login * @property {WSEventType[]} [disabledEvents] An array of disabled websocket events. Events in this array will not be * processed, potentially resulting in performance improvements for larger bots. Only disable events you are @@ -48,6 +50,7 @@ exports.DefaultOptions = { restWsBridgeTimeout: 5000, disabledEvents: [], restTimeOffset: 500, + restSweepInterval: 60, presence: {}, /**