From b6955db96fb42cb436e7a9d33575baedac7a63b3 Mon Sep 17 00:00:00 2001 From: Skillz4Killz <23035000+Skillz4Killz@users.noreply.github.com> Date: Tue, 16 Feb 2021 02:16:32 +0000 Subject: [PATCH] almost done, only workers left --- src/ws/README.md | 148 ++++++++++++++++++++++++++++++++++++++++ src/ws/proxy/manager.ts | 6 +- 2 files changed, 152 insertions(+), 2 deletions(-) diff --git a/src/ws/README.md b/src/ws/README.md index d7c332799..77e1bb7a5 100644 --- a/src/ws/README.md +++ b/src/ws/README.md @@ -54,3 +54,151 @@ This WS service is meant for ADVANCED DEVELOPERS ONLY! - Take full advantage of all your CPU cores by using workers to spread the load. Control how many shards per worker and how many workers to maximize efficiency! + +## Usage + +```ts +startGateway({ + /** The bot token. */ + token: "BOT_TOKEN_HERE", + /** Whether or not to use compression for gateway payloads. */ + compress: true, + /** The intents you would like to enable. */ + intents: ["GUILDS", "GUILD_MESSAGES"], + /** The max amount of shards used for identifying. This can be useful for zero-downtime updates or resharding. */ + maxShards: 885, + /** The first shard ID for this group of shards. */ + firstShardID: 100, + /** The last shard ID for this group. If none is provided, it will default to loading all shards. */ + lastShardID: 124, + /** The url to forward all payloads to. */ + url: "http://urlToYourServerHere", + /** The amount of shards per cluster. By default this is 25. Use this to spread the load from shards to different CPU cores. */ + shardsPerCluster: 25, + /** The maximum amount of clusters available. By default this is 4. Another way to think of cluster is how many CPU cores does your server/machine have. */ + maxClusters: 46, + /** Whether or not you want to allow automated sharding. By default this is true. */ + reshard: true; +}); +``` + +## API / Docs + +```ts +// CONTROLLER LIKE INTERFACE FOR WS HANDLING +export const ws = { + /** The url that all discord payloads for the dispatch type should be sent to. */ + url: "", + /** Whether or not to automatically reshard. */ + reshard: true, + /** The percentage at which resharding should occur. */ + reshardPercentage: 80, + /** The maximum shard ID number. Useful for zero-downtime updates or resharding. */ + maxShards: 1, + /** The amount of shards to load per cluster */ + shardsPerCluster: 25, + /** The maximum amount of clusters to use for your bot. */ + maxClusters: 4, + /** The first shard ID to start spawning. */ + firstShardID: 0, + /** The last shard ID for this cluster. */ + lastShardID: 1, + /** This prop decides whether Discord allows our next shard to be started. When 1 starts, this is set to false until it is ready for the next one. */ + createNextShard: true, + /** The identify payload holds the necessary data to connect and stay connected with Discords WSS. */ + identifyPayload: { + token: "", + compress: false, + properties: { + $os: "linux", + $browser: "Discordeno", + $device: "Discordeno", + }, + intents: 0, + shard: [0, 0], + }, + botGatewayData: { + /** The WSS URL that can be used for connecting to the gateway. */ + url: "wss://gateway.discord.gg/?v=8&encoding=json", + /** The recommended number of shards to use when connecting. */ + shards: 1, + /** Info on the current start limit. */ + sessionStartLimit: { + /** The total number of session starts the current user is allowed. */ + total: 1000, + /** The remaining number of session starts the current user is allowed. */ + remaining: 1000, + /** Milliseconds left until limit is reset. */ + resetAfter: 0, + /** The number of identify requests allowed per 5 seconds. + * So, if you had a max concurrency of 16, and 16 shards for example, you could start them all up at the same time. + * Whereas if you had 32 shards, if you tried to start up shard 0 and 16 at the same time for example, it would not work. You can start shards 0-15 concurrently, then 16-31... + */ + maxConcurrency: 1, + }, + }, + shards: new Collection(), + loadingShards: new Collection< + number, + { + shardID: number; + resolve: (value: unknown) => void; + reject: (reason?: unknown) => void; + startedAt: number; + } + >(), + utf8decoder: new TextDecoder(), + + // METHODS + + /** The handler function that starts the gateway. */ + startGateway, + /** The handler for spawning ALL the shards. */ + spawnShards, + /** Create the websocket and adds the proper handlers to the websocket. */ + createShard, + /** Begins identification of the shard to discord */ + identify, + /** Begins heartbeating of the shard to keep it alive */ + heartbeat, + /** Sends the discord payload to another server. */ + handleDiscordPayload, + /** Tell the cluster/worker to begin identifying this shard */ + tellClusterToIdentify, + /** Handle the different logs. Used for debugging. */ + log, + /** Handles resharding the bot when necessary. */ + resharder, + /** Cleanups loading shards that were unable to load. */ + cleanupLoadingShards, +}; + +export interface DiscordenoShard { + /** The shard id number */ + id: number; + /** The websocket for this shard */ + ws: WebSocket; + /** The amount of milliseconds to wait between heartbeats */ + resumeInterval: number; + /** The session id important for resuming connections. */ + sessionID: string; + /** The previous sequence number, important for resuming connections. */ + previousSequenceNumber: number | null; + /** Whether the shard is currently resuming. */ + resuming: boolean; + heartbeat: { + /** The exact timestamp the last heartbeat was sent */ + lastSentAt: number; + /** The timestamp the last heartbeat ACK was received from discord. */ + lastReceivedAt: number; + /** Whether or not the heartbeat was acknowledged by discord in time. */ + acknowledged: boolean; + /** Whether or not to keep heartbeating. Useful for when needing to stop heartbeating. */ + keepAlive: boolean; + /** The interval between heartbeats requested by discord. */ + interval: number; + /** The id of the interval, useful for stopping the interval if ws closed. */ + intervalID: number; + }; +} +``` \ No newline at end of file diff --git a/src/ws/proxy/manager.ts b/src/ws/proxy/manager.ts index 149399a79..349e7b11e 100644 --- a/src/ws/proxy/manager.ts +++ b/src/ws/proxy/manager.ts @@ -98,12 +98,14 @@ export function spawnShards(firstShardID = 0) { /** Allows users to hook in and change to communicate to different clusters across different servers or anything they like. For example using redis pubsub to talk to other servers. */ export async function tellClusterToIdentify( - clusterID: number, + workerID: number, shardID: number, bucketID: number, ) { - // When resharding + // When resharding this may exist already const oldShard = ws.shards.get(shardID); + + // TODO: Use workers await ws.identify(shardID, ws.maxShards); if (oldShard) {