This commit is contained in:
Skillz
2020-11-03 15:18:14 -05:00
parent c2e4c19d41
commit 5567593779
3 changed files with 33 additions and 53 deletions
+1 -1
View File
@@ -51,7 +51,7 @@ export async function createBasicShard(
const basicShard: BasicShard = { const basicShard: BasicShard = {
id: shardID, id: shardID,
socket: await connectWebSocket(`${data.url}?v=6&encoding=json`), socket: await connectWebSocket(`${data.url}?v=8&encoding=json`),
resumeInterval: 0, resumeInterval: 0,
sessionID: oldShard?.sessionID || "", sessionID: oldShard?.sessionID || "",
previousSequenceNumber: oldShard?.previousSequenceNumber || 0, previousSequenceNumber: oldShard?.previousSequenceNumber || 0,
+7 -52
View File
@@ -1,16 +1,12 @@
import { delay } from "../../deps.ts"; import { DiscordBotGatewayData, RequestManager, spawnBigBrainBotShards } from "../../mod.ts";
import { DiscordBotGatewayData, RequestManager } from "../../mod.ts";
import { endpoints } from "../constants/discord.ts"; import { endpoints } from "../constants/discord.ts";
import { ClientOptions, EventHandlers } from "../types/options.ts"; import { ClientOptions, EventHandlers } from "../types/options.ts";
import { botGatewayData } from "./client.ts";
const botOptions = { const botOptions = {
createNextShard: false, createNextShard: false,
workers: new Map<number, Worker>(), workers: new Map<number, Worker>(),
eventHandlers: {} as EventHandlers, eventHandlers: {} as EventHandlers,
botGatewayData: {} as DiscordBotGatewayData, botGatewayData: {} as DiscordBotGatewayData,
customShards: [] as number[],
shardsPerWorker: 25,
identifyPayload: { identifyPayload: {
token: "", token: "",
compress: true, compress: true,
@@ -20,7 +16,7 @@ const botOptions = {
$device: "Discordeno", $device: "Discordeno",
}, },
intents: 0, intents: 0,
shard: [0, 0], shard: [0, 0] as [number, number],
}, },
}; };
@@ -33,9 +29,7 @@ const botOptions = {
export async function startBigBrainBot(data: BigBrainBotOptions) { export async function startBigBrainBot(data: BigBrainBotOptions) {
botOptions.identifyPayload.token = `Bot ${data.token}`; botOptions.identifyPayload.token = `Bot ${data.token}`;
if (data.eventHandlers) botOptions.eventHandlers = data.eventHandlers; if (data.eventHandlers) botOptions.eventHandlers = data.eventHandlers;
if (data.shards) botOptions.customShards = data.shards;
if (data.compress) botOptions.identifyPayload.compress = data.compress; if (data.compress) botOptions.identifyPayload.compress = data.compress;
if (data.shardsPerWorker) botOptions.shardsPerWorker = data.shardsPerWorker;
// Initial API connection to get info about bots connection // Initial API connection to get info about bots connection
botOptions.botGatewayData = await RequestManager.get( botOptions.botGatewayData = await RequestManager.get(
@@ -46,58 +40,19 @@ export async function startBigBrainBot(data: BigBrainBotOptions) {
(bits, next) => (bits |= next), (bits, next) => (bits |= next),
0, 0,
); );
botOptions.identifyPayload.shard = [0, botGatewayData.shards];
spawnBigBrainBotShards(); spawnBigBrainBotShards(botOptions.botGatewayData, botOptions.identifyPayload, data.firstShardID, data.lastShardID || (data.firstShardID + 25));
} }
async function spawnBigBrainBotShards(shardID = 0, skipChecks = 0) {
if (shardID >= botOptions.botGatewayData.shards) return;
// 25 shards but shards start at 0 so we use 24
const workerID = shardID % botOptions.shardsPerWorker - 1;
const worker = botOptions.workers.get(workerID)
// High max concurrency allows starting shards faster
if (skipChecks) {
// If the worker exists we just need to add
if (worker) {
worker.postMessage({ type: "CREATE_SHARD", shardID, workerID, botOptions });
} else {
const path = new URL("./shard.ts", import.meta.url).toString();
const newWorker = new Worker(path, { type: "module", deno: true });
// Add to worker map
botOptions.workers.set(workerID, newWorker);
newWorker.postMessage({ type: "CREATE_SHARD", shardID, workerID, botOptions });
}
spawnBigBrainBotShards(shardID + 1, skipChecks - 1);
}
// Make sure we can create a shard or we are waiting for shards to connect still.
if (botOptions.createNextShard) {
// !(shardid % botOptions.botGatewayData.session_start_limit.max_concurrency)
botOptions.createNextShard = false;
// Start the next few shards based on max concurrency
spawnBigBrainBotShards(shardID + 1, botOptions.botGatewayData.session_start_limit.max_concurrency);
return;
}
await delay(1000);
spawnBigBrainBotShards(shardID);
}
export interface BigBrainBotOptions extends ClientOptions { export interface BigBrainBotOptions extends ClientOptions {
/** This can be used to distribute your bot across different servers. For example, if you wanted 1 million shards per server you could control it using this. */ /** The first shard to start at for this worker. Use this to control which shards to run in each worker. */
shards?: [number, number]; firstShardID: number;
/** The last shard to start for this worker. By default it will be 25 + the firstShardID. */
lastShardID?: number;
/** This can be used to forward the ws handling to a proxy. */ /** This can be used to forward the ws handling to a proxy. */
wsURL?: string; wsURL?: string;
/** This can be used to forward the REST handling to a proxy. */ /** This can be used to forward the REST handling to a proxy. */
restURL?: string; restURL?: string;
/** This allows you to control how many shards per worker. For the times where you can optimize with more shards per worker as your bot has less tasks per shard.
* @default 25
*/
shardsPerWorker?: number;
/** The absolute file path to the file where the worker will run. */
workerFilePath?: string;
} }
+25
View File
@@ -60,6 +60,31 @@ export function createShardWorker(shardID?: number) {
shards.push(shard); shards.push(shard);
} }
export async function spawnBigBrainBotShards(data: DiscordBotGatewayData, payload: IdentifyPayload, shardID: number, lastShardID: number, skipChecks?: number) {
// All shards on this worker have started! Cancel out.
if (shardID > lastShardID) return;
if (skipChecks) {
payload.shard = [shardID, data.shards];
// Start The shard
createBasicShard(data, payload, false, shardID);
// Spawn next shard
spawnBigBrainBotShards(data, payload, shardID, lastShardID, skipChecks - 1);
return;
}
// Make sure we can create a shard or we are waiting for shards to connect still.
if (createNextShard) {
createNextShard = false;
// Start the next few shards based on max concurrency
spawnBigBrainBotShards(data, payload, shardID + 1, lastShardID, data.session_start_limit.max_concurrency);
return;
}
await delay(1000);
spawnBigBrainBotShards(data, payload, shardID, lastShardID, skipChecks);
}
export const spawnShards = async ( export const spawnShards = async (
data: DiscordBotGatewayData, data: DiscordBotGatewayData,
payload: IdentifyPayload, payload: IdentifyPayload,