Skip to content

Commit

Permalink
fix: retry connection when failed
Browse files Browse the repository at this point in the history
  • Loading branch information
MARCROCK22 committed Feb 23, 2025
1 parent 61c3c28 commit 272ddac
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 4 deletions.
29 changes: 25 additions & 4 deletions src/websocket/discord/shard.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { inflateSync } from 'node:zlib';
import { LogLevels, Logger, type MakeRequired, MergeOptions, hasIntent } from '../../common';
import { LogLevels, Logger, type MakeRequired, MergeOptions, delay, hasIntent } from '../../common';
import {
type APIGuildMember,
GatewayCloseCodes,
Expand Down Expand Up @@ -46,8 +46,11 @@ export class Shard {
bucket: DynamicBucket;
offlineSendQueue: ((_?: unknown) => void)[] = [];
pendingGuilds = new Set<string>();
options: MakeRequired<ShardOptions, 'properties' | 'ratelimitOptions'>;
options: MakeRequired<ShardOptions, 'properties' | 'ratelimitOptions' | 'reconnectTimeout' | 'connectionTimeout'>;
isReady = false;

connectionTimeout?: NodeJS.Timeout;

private requestGuildMembersChunk = new Map<
string,
{
Expand All @@ -72,6 +75,8 @@ export class Shard {
rateLimitResetInterval: 60_000,
maxRequestsPerRateLimitTick: 120,
},
reconnectTimeout: 10e3,
connectionTimeout: 30e3,
} as ShardOptions,
options,
);
Expand Down Expand Up @@ -127,6 +132,11 @@ export class Shard {

this.debugger?.debug(`[Shard #${this.id}] Connecting to ${this.currentGatewayURL}`);

this.connectionTimeout = setTimeout(
() => this.reconnect(ShardSocketCloseCodes.Timeout),
this.options.connectionTimeout,
);

// @ts-expect-error Use native websocket when using Bun
// biome-ignore lint/correctness/noUndeclaredVariables: /\
this.websocket = new BaseSocket(typeof Bun === 'undefined' ? 'ws' : 'bun', this.currentGatewayURL);
Expand Down Expand Up @@ -217,13 +227,16 @@ export class Shard {
}

disconnect(code = ShardSocketCloseCodes.Shutdown) {
clearTimeout(this.connectionTimeout);
this.connectionTimeout = undefined;
this.debugger?.info(`[Shard #${this.id}] Disconnecting`);
this.close(code, 'Shard down request');
}

async reconnect() {
async reconnect(code = ShardSocketCloseCodes.Reconnect) {
this.debugger?.info(`[Shard #${this.id}] Reconnecting`);
this.disconnect(ShardSocketCloseCodes.Reconnect);
this.disconnect(code);
await delay(this.options.reconnectTimeout);
await this.connect();
}

Expand All @@ -236,6 +249,8 @@ export class Shard {

switch (packet.op) {
case GatewayOpcodes.Hello: {
clearTimeout(this.connectionTimeout);
this.connectionTimeout = undefined;
clearInterval(this.heart.nodeInterval);

this.heart.interval = packet.d.heartbeat_interval;
Expand Down Expand Up @@ -275,12 +290,16 @@ export class Shard {
switch (packet.t) {
case GatewayDispatchEvents.Resumed:
{
clearTimeout(this.connectionTimeout);
this.connectionTimeout = undefined;
this.isReady = true;
this.offlineSendQueue.map(resolve => resolve());
this.options.handlePayload(this.id, packet);
}
break;
case GatewayDispatchEvents.Ready: {
clearTimeout(this.connectionTimeout);
this.connectionTimeout = undefined;
if (hasIntent(this.options.intents, 'Guilds')) {
for (let i = 0; i < packet.d.guilds.length; i++) {
this.pendingGuilds.add(packet.d.guilds.at(i)!.id);
Expand Down Expand Up @@ -411,6 +430,8 @@ export class Shard {
case GatewayCloseCodes.UnknownOpcode:
case GatewayCloseCodes.InvalidSeq:
case GatewayCloseCodes.SessionTimedOut:
// shard failed to connect, try connecting from scratch
case ShardSocketCloseCodes.Timeout:
{
this.data.resume_seq = 0;
this.data.session_id = undefined;
Expand Down
2 changes: 2 additions & 0 deletions src/websocket/discord/sharder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,8 @@ export class ShardManager extends Map<number, Shard> {
debugger: this.debugger,
compress: this.options.compress ?? false,
presence: this.options.presence?.(shardId, -1),
connectionTimeout: this.options.connectionTimeout,
reconnectTimeout: this.options.reconnectTimeout,
});

this.set(shardId, shard);
Expand Down
5 changes: 5 additions & 0 deletions src/websocket/discord/shared.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ export interface ShardManagerOptions extends ShardDetails {
interval: number;
percentage: number;
};
reconnectTimeout?: number;
connectionTimeout?: number;
}

export interface CustomManagerAdapter {
Expand Down Expand Up @@ -128,6 +130,8 @@ export interface ShardOptions extends ShardDetails {
debugger?: Logger;
compress: boolean;
presence?: GatewayPresenceUpdateData;
reconnectTimeout?: number;
connectionTimeout?: number;
}

export enum ShardSocketCloseCodes {
Expand All @@ -136,6 +140,7 @@ export enum ShardSocketCloseCodes {
Reconnect = 3020,
Resharding = 3030,
ShutdownAll = 3040,
Timeout = 3050,
}

export interface WorkerData {
Expand Down

0 comments on commit 272ddac

Please sign in to comment.