Add files via upload
This commit is contained in:
2673
node_modules/eris/lib/gateway/Shard.js
generated
vendored
Normal file
2673
node_modules/eris/lib/gateway/Shard.js
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
164
node_modules/eris/lib/gateway/ShardManager.js
generated
vendored
Normal file
164
node_modules/eris/lib/gateway/ShardManager.js
generated
vendored
Normal file
@ -0,0 +1,164 @@
|
||||
"use strict";
|
||||
|
||||
const Base = require("../structures/Base");
|
||||
const Collection = require("../util/Collection");
|
||||
const Shard = require("./Shard");
|
||||
|
||||
class ShardManager extends Collection {
|
||||
constructor(client, options = {}) {
|
||||
super(Shard);
|
||||
this._client = client;
|
||||
|
||||
this.options = Object.assign({
|
||||
concurrency: 1
|
||||
}, options);
|
||||
|
||||
this.buckets = new Map();
|
||||
this.connectQueue = [];
|
||||
this.connectTimeout = null;
|
||||
}
|
||||
|
||||
connect(shard) {
|
||||
this.connectQueue.push(shard);
|
||||
this.tryConnect();
|
||||
}
|
||||
|
||||
setConcurrency(concurrency) {
|
||||
this.options.concurrency = concurrency;
|
||||
}
|
||||
|
||||
spawn(id) {
|
||||
let shard = this.get(id);
|
||||
if(!shard) {
|
||||
shard = this.add(new Shard(id, this._client));
|
||||
shard.on("ready", () => {
|
||||
/**
|
||||
* Fired when a shard turns ready
|
||||
* @event Client#shardReady
|
||||
* @prop {Number} id The ID of the shard
|
||||
*/
|
||||
this._client.emit("shardReady", shard.id);
|
||||
if(this._client.ready) {
|
||||
return;
|
||||
}
|
||||
for(const other of this.values()) {
|
||||
if(!other.ready) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
this._client.ready = true;
|
||||
this._client.startTime = Date.now();
|
||||
/**
|
||||
* Fired when all shards turn ready
|
||||
* @event Client#ready
|
||||
*/
|
||||
this._client.emit("ready");
|
||||
}).on("resume", () => {
|
||||
/**
|
||||
* Fired when a shard resumes
|
||||
* @event Client#shardResume
|
||||
* @prop {Number} id The ID of the shard
|
||||
*/
|
||||
this._client.emit("shardResume", shard.id);
|
||||
if(this._client.ready) {
|
||||
return;
|
||||
}
|
||||
for(const other of this.values()) {
|
||||
if(!other.ready) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
this._client.ready = true;
|
||||
this._client.startTime = Date.now();
|
||||
this._client.emit("ready");
|
||||
}).on("disconnect", (error) => {
|
||||
/**
|
||||
* Fired when a shard disconnects
|
||||
* @event Client#shardDisconnect
|
||||
* @prop {Error?} error The error, if any
|
||||
* @prop {Number} id The ID of the shard
|
||||
*/
|
||||
this._client.emit("shardDisconnect", error, shard.id);
|
||||
for(const other of this.values()) {
|
||||
if(other.ready) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
this._client.ready = false;
|
||||
this._client.startTime = 0;
|
||||
/**
|
||||
* Fired when all shards disconnect
|
||||
* @event Client#disconnect
|
||||
*/
|
||||
this._client.emit("disconnect");
|
||||
});
|
||||
}
|
||||
if(shard.status === "disconnected") {
|
||||
return this.connect(shard);
|
||||
}
|
||||
}
|
||||
|
||||
tryConnect() {
|
||||
// nothing in queue
|
||||
if(this.connectQueue.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// loop over the connectQueue
|
||||
for(const shard of this.connectQueue) {
|
||||
// find the bucket for our shard
|
||||
const rateLimitKey = (shard.id % this.options.concurrency) || 0;
|
||||
const lastConnect = this.buckets.get(rateLimitKey) || 0;
|
||||
|
||||
// has enough time passed since the last connect for this bucket (5s/bucket)?
|
||||
// alternatively if we have a sessionID, we can skip this check
|
||||
if(!shard.sessionID && Date.now() - lastConnect < 5000) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Are there any connecting shards in the same bucket we should wait on?
|
||||
if(this.some((s) => s.connecting && ((s.id % this.options.concurrency) || 0) === rateLimitKey)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// connect the shard
|
||||
shard.connect();
|
||||
this.buckets.set(rateLimitKey, Date.now());
|
||||
|
||||
// remove the shard from the queue
|
||||
const index = this.connectQueue.findIndex((s) => s.id === shard.id);
|
||||
this.connectQueue.splice(index, 1);
|
||||
}
|
||||
|
||||
// set the next timeout if we have more shards to connect
|
||||
if(!this.connectTimeout && this.connectQueue.length > 0) {
|
||||
this.connectTimeout = setTimeout(() => {
|
||||
this.connectTimeout = null;
|
||||
this.tryConnect();
|
||||
}, 500);
|
||||
}
|
||||
}
|
||||
|
||||
_readyPacketCB(shardID) {
|
||||
const rateLimitKey = (shardID % this.options.concurrency) || 0;
|
||||
this.buckets.set(rateLimitKey, Date.now());
|
||||
|
||||
this.tryConnect();
|
||||
}
|
||||
|
||||
toString() {
|
||||
return `[ShardManager ${this.size}]`;
|
||||
}
|
||||
|
||||
toJSON(props = []) {
|
||||
return Base.prototype.toJSON.call(this, [
|
||||
"buckets",
|
||||
"connectQueue",
|
||||
"connectTimeout",
|
||||
"options",
|
||||
...props
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = ShardManager;
|
Reference in New Issue
Block a user