Skip to content

Commit

Permalink
refactor: remove timer utilities from Client (#6113)
Browse files Browse the repository at this point in the history
  • Loading branch information
kyranet committed Jul 16, 2021
1 parent f200f14 commit 5ca97c9
Show file tree
Hide file tree
Showing 13 changed files with 47 additions and 145 deletions.
97 changes: 2 additions & 95 deletions src/client/BaseClient.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,27 +13,6 @@ class BaseClient extends EventEmitter {
constructor(options = {}) {
super();

/**
* Timeouts set by {@link BaseClient#setTimeout} that are still active
* @type {Set<Timeout>}
* @private
*/
this._timeouts = new Set();

/**
* Intervals set by {@link BaseClient#setInterval} that are still active
* @type {Set<Timeout>}
* @private
*/
this._intervals = new Set();

/**
* Intervals set by {@link BaseClient#setImmediate} that are still active
* @type {Set<Immediate>}
* @private
*/
this._immediates = new Set();

/**
* The options the client was instantiated with
* @type {ClientOptions}
Expand All @@ -60,82 +39,10 @@ class BaseClient extends EventEmitter {

/**
* Destroys all assets used by the base client.
* @returns {void}
*/
destroy() {
for (const t of this._timeouts) this.clearTimeout(t);
for (const i of this._intervals) this.clearInterval(i);
for (const i of this._immediates) this.clearImmediate(i);
this._timeouts.clear();
this._intervals.clear();
this._immediates.clear();
}

/**
* Sets a timeout that will be automatically cancelled if the client is destroyed.
* @param {Function} fn Function to execute
* @param {number} delay Time to wait before executing (in milliseconds)
* @param {...*} args Arguments for the function
* @returns {Timeout}
*/
setTimeout(fn, delay, ...args) {
const timeout = setTimeout(() => {
fn(...args);
this._timeouts.delete(timeout);
}, delay);
this._timeouts.add(timeout);
return timeout;
}

/**
* Clears a timeout.
* @param {Timeout} timeout Timeout to cancel
*/
clearTimeout(timeout) {
clearTimeout(timeout);
this._timeouts.delete(timeout);
}

/**
* Sets an interval that will be automatically cancelled if the client is destroyed.
* @param {Function} fn Function to execute
* @param {number} delay Time to wait between executions (in milliseconds)
* @param {...*} args Arguments for the function
* @returns {Timeout}
*/
setInterval(fn, delay, ...args) {
const interval = setInterval(fn, delay, ...args);
this._intervals.add(interval);
return interval;
}

/**
* Clears an interval.
* @param {Timeout} interval Interval to cancel
*/
clearInterval(interval) {
clearInterval(interval);
this._intervals.delete(interval);
}

/**
* Sets an immediate that will be automatically cancelled if the client is destroyed.
* @param {Function} fn Function to execute
* @param {...*} args Arguments for the function
* @returns {Immediate}
*/
setImmediate(fn, ...args) {
const immediate = setImmediate(fn, ...args);
this._immediates.add(immediate);
return immediate;
}

/**
* Clears an immediate.
* @param {Immediate} immediate Immediate to cancel
*/
clearImmediate(immediate) {
clearImmediate(immediate);
this._immediates.delete(immediate);
if (this.rest.sweepInterval) clearInterval(this.rest.sweepInterval);
}

/**
Expand Down
7 changes: 6 additions & 1 deletion src/client/Client.js
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,10 @@ class Client extends BaseClient {
this.readyAt = null;

if (this.options.messageSweepInterval > 0) {
this.setInterval(this.sweepMessages.bind(this), this.options.messageSweepInterval * 1000);
this.sweepMessageInterval = setInterval(
this.sweepMessages.bind(this),
this.options.messageSweepInterval * 1000,
).unref();
}
}

Expand Down Expand Up @@ -242,6 +245,8 @@ class Client extends BaseClient {
*/
destroy() {
super.destroy();
if (this.sweepMessageInterval) clearInterval(this.sweepMessageInterval);

this.ws.destroy();
this.token = null;
}
Expand Down
2 changes: 1 addition & 1 deletion src/client/actions/GuildDelete.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ class GuildDeleteAction extends Action {
}

scheduleForDeletion(id) {
this.client.setTimeout(() => this.deleted.delete(id), this.client.options.restWsBridgeTimeout);
setTimeout(() => this.deleted.delete(id), this.client.options.restWsBridgeTimeout).unref();
}
}

Expand Down
4 changes: 2 additions & 2 deletions src/client/websocket/WebSocketManager.js
Original file line number Diff line number Diff line change
Expand Up @@ -336,9 +336,9 @@ class WebSocketManager extends EventEmitter {

if (this.packetQueue.length) {
const item = this.packetQueue.shift();
this.client.setImmediate(() => {
setImmediate(() => {
this.handlePacket(item.packet, item.shard);
});
}).unref();
}

if (packet && PacketHandlers[packet.t]) {
Expand Down
24 changes: 12 additions & 12 deletions src/client/websocket/WebSocketShard.js
Original file line number Diff line number Diff line change
Expand Up @@ -455,7 +455,7 @@ class WebSocketShard extends EventEmitter {
checkReady() {
// Step 0. Clear the ready timeout, if it exists
if (this.readyTimeout) {
this.manager.client.clearTimeout(this.readyTimeout);
clearTimeout(this.readyTimeout);
this.readyTimeout = null;
}
// Step 1. If we don't have any other guilds pending, we are ready
Expand All @@ -475,7 +475,7 @@ class WebSocketShard extends EventEmitter {
return;
}
// Step 2. Create a 15s timeout that will mark the shard as ready if there are still unavailable guilds
this.readyTimeout = this.manager.client.setTimeout(() => {
this.readyTimeout = setTimeout(() => {
this.debug(`Shard did not receive any more guild packets in 15 seconds.
Unavailable guild count: ${this.expectedGuilds.size}`);

Expand All @@ -484,7 +484,7 @@ class WebSocketShard extends EventEmitter {
this.status = Status.READY;

this.emit(ShardEvents.ALL_READY, this.expectedGuilds);
}, 15000);
}, 15000).unref();
}

/**
Expand All @@ -496,16 +496,16 @@ class WebSocketShard extends EventEmitter {
if (time === -1) {
if (this.helloTimeout) {
this.debug('Clearing the HELLO timeout.');
this.manager.client.clearTimeout(this.helloTimeout);
clearTimeout(this.helloTimeout);
this.helloTimeout = null;
}
return;
}
this.debug('Setting a HELLO timeout for 20s.');
this.helloTimeout = this.manager.client.setTimeout(() => {
this.helloTimeout = setTimeout(() => {
this.debug('Did not receive HELLO in time. Destroying and connecting again.');
this.destroy({ reset: true, closeCode: 4009 });
}, 20000);
}, 20000).unref();
}

/**
Expand All @@ -517,15 +517,15 @@ class WebSocketShard extends EventEmitter {
if (time === -1) {
if (this.heartbeatInterval) {
this.debug('Clearing the heartbeat interval.');
this.manager.client.clearInterval(this.heartbeatInterval);
clearInterval(this.heartbeatInterval);
this.heartbeatInterval = null;
}
return;
}
this.debug(`Setting a heartbeat interval for ${time}ms.`);
// Sanity checks
if (this.heartbeatInterval) this.manager.client.clearInterval(this.heartbeatInterval);
this.heartbeatInterval = this.manager.client.setInterval(() => this.sendHeartbeat(), time);
if (this.heartbeatInterval) clearInterval(this.heartbeatInterval);
this.heartbeatInterval = setInterval(() => this.sendHeartbeat(), time).unref();
}

/**
Expand Down Expand Up @@ -668,10 +668,10 @@ class WebSocketShard extends EventEmitter {
if (this.ratelimit.remaining === 0) return;
if (this.ratelimit.queue.length === 0) return;
if (this.ratelimit.remaining === this.ratelimit.total) {
this.ratelimit.timer = this.manager.client.setTimeout(() => {
this.ratelimit.timer = setTimeout(() => {
this.ratelimit.remaining = this.ratelimit.total;
this.processQueue();
}, this.ratelimit.time);
}, this.ratelimit.time).unref();
}
while (this.ratelimit.remaining > 0) {
const item = this.ratelimit.queue.shift();
Expand Down Expand Up @@ -741,7 +741,7 @@ class WebSocketShard extends EventEmitter {
this.ratelimit.remaining = this.ratelimit.total;
this.ratelimit.queue.length = 0;
if (this.ratelimit.timer) {
this.manager.client.clearTimeout(this.ratelimit.timer);
clearTimeout(this.ratelimit.timer);
this.ratelimit.timer = null;
}
}
Expand Down
6 changes: 3 additions & 3 deletions src/managers/GuildManager.js
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,7 @@ class GuildManager extends CachedManager {

const handleGuild = guild => {
if (guild.id === data.id) {
this.client.clearTimeout(timeout);
clearTimeout(timeout);
this.client.removeListener(Events.GUILD_CREATE, handleGuild);
this.client.decrementMaxListeners();
resolve(guild);
Expand All @@ -226,11 +226,11 @@ class GuildManager extends CachedManager {
this.client.incrementMaxListeners();
this.client.on(Events.GUILD_CREATE, handleGuild);

const timeout = this.client.setTimeout(() => {
const timeout = setTimeout(() => {
this.client.removeListener(Events.GUILD_CREATE, handleGuild);
this.client.decrementMaxListeners();
resolve(this.client.guilds._add(data));
}, 10000);
}, 10000).unref();
return undefined;
}, reject),
);
Expand Down
6 changes: 3 additions & 3 deletions src/managers/GuildMemberManager.js
Original file line number Diff line number Diff line change
Expand Up @@ -372,19 +372,19 @@ class GuildMemberManager extends CachedManager {
(limit && fetchedMembers.size >= limit) ||
i === chunk.count
) {
this.client.clearTimeout(timeout);
clearTimeout(timeout);
this.client.removeListener(Events.GUILD_MEMBERS_CHUNK, handler);
this.client.decrementMaxListeners();
let fetched = option ? fetchedMembers : this.cache;
if (user_ids && !Array.isArray(user_ids) && fetched.size) fetched = fetched.first();
resolve(fetched);
}
};
const timeout = this.client.setTimeout(() => {
const timeout = setTimeout(() => {
this.client.removeListener(Events.GUILD_MEMBERS_CHUNK, handler);
this.client.decrementMaxListeners();
reject(new Error('GUILD_MEMBERS_TIMEOUT'));
}, time);
}, time).unref();
this.client.incrementMaxListeners();
this.client.on(Events.GUILD_MEMBERS_CHUNK, handler);
});
Expand Down
4 changes: 2 additions & 2 deletions src/rest/APIRequest.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,14 +59,14 @@ class APIRequest {
}

const controller = new AbortController();
const timeout = this.client.setTimeout(() => controller.abort(), this.client.options.restRequestTimeout);
const timeout = setTimeout(() => controller.abort(), this.client.options.restRequestTimeout).unref();
return fetch(url, {
method: this.method,
headers,
agent,
body,
signal: controller.signal,
}).finally(() => this.client.clearTimeout(timeout));
}).finally(() => clearTimeout(timeout));
}
}

Expand Down
5 changes: 2 additions & 3 deletions src/rest/RESTManager.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,9 @@ class RESTManager {
this.globalReset = null;
this.globalDelay = null;
if (client.options.restSweepInterval > 0) {
const interval = client.setInterval(() => {
this.sweepInterval = setInterval(() => {
this.handlers.sweep(handler => handler._inactive);
}, client.options.restSweepInterval * 1000);
interval.unref();
}, client.options.restSweepInterval * 1000).unref();
}
}

Expand Down
4 changes: 2 additions & 2 deletions src/rest/RequestHandler.js
Original file line number Diff line number Diff line change
Expand Up @@ -71,10 +71,10 @@ class RequestHandler {

globalDelayFor(ms) {
return new Promise(resolve => {
this.manager.client.setTimeout(() => {
setTimeout(() => {
this.manager.globalDelay = null;
resolve();
}, ms);
}, ms).unref();
});
}

Expand Down
4 changes: 2 additions & 2 deletions src/structures/GuildTemplate.js
Original file line number Diff line number Diff line change
Expand Up @@ -122,15 +122,15 @@ class GuildTemplate extends Base {

const handleGuild = guild => {
if (guild.id === data.id) {
client.clearTimeout(timeout);
clearTimeout(timeout);
resolveGuild(guild);
}
};

client.incrementMaxListeners();
client.on(Events.GUILD_CREATE, handleGuild);

const timeout = client.setTimeout(() => resolveGuild(client.guilds._add(data)), 10000);
const timeout = setTimeout(() => resolveGuild(client.guilds._add(data)), 10000).unref();
});
}

Expand Down
Loading

0 comments on commit 5ca97c9

Please sign in to comment.