fix resume bug (#157)

This commit is contained in:
MARCROCK22 2023-12-08 18:59:49 -04:00 committed by GitHub
parent 0fcc92ab26
commit ca116f85ee
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 22 additions and 43 deletions

View File

@ -30,7 +30,7 @@ export class ShardHeartBeater {
interval: 30_000
};
// biome-ignore lint/nursery/noEmptyBlockStatements: <explanation>
constructor(public shard: Shard) {}
constructor(public shard: Shard) { }
acknowledge(ack = true) {
this.heart.ack = ack;
@ -106,6 +106,12 @@ export class ShardHeartBeater {
}
this.startHeartBeating();
if (this.shard.data.session_id) {
this.shard.resume();
} else {
this.shard.identify()
}
}
onpacket(packet: GatewayReceivePayload) {

View File

@ -47,7 +47,6 @@ export class Shard {
}
isOpen() {
this.logger.fatal(`[Shard #${this.id}]`, "isOpen", this.websocket?.readyState === WebSocket.OPEN);
return this.websocket?.readyState === WebSocket.OPEN;
}
@ -67,7 +66,6 @@ export class Shard {
}
connect() {
this.logger.fatal(`[Shard #${this.id}]`, "Connect", this.state);
if (![ShardState.Resuming, ShardState.Identifying].includes(this.state)) {
this.state = ShardState.Connecting;
}
@ -96,30 +94,17 @@ export class Shard {
}
checkOffline(priority: number) {
// biome-ignore lint/style/noArguments: <explanation>
// biome-ignore lint/correctness/noUndeclaredVariables: <explanation>
this.logger.fatal(`[Shard #${this.id}]`, "checkOffline", ...arguments);
if (!this.isOpen()) {
return new Promise((resolve) => this.offlineSendQueue.push(resolve, priority));
}
return Promise.resolve();
}
async identify(justTry = false) {
this.logger.debug(`[Shard #${this.id}] ${justTry ? "Trying " : ""}on identify ${this.isOpen()}`);
if (this.isOpen()) {
if (justTry) return;
this.logger.debug(`[Shard #${this.id}] CLOSING EXISTING SHARD`);
this.close(ShardSocketCloseCodes.ReIdentifying, "Re-identifying closure of old connection.");
}
async identify() {
this.logger.debug(`[Shard #${this.id}] on identify ${this.isOpen()}`);
this.state = ShardState.Identifying;
if (!this.isOpen()) {
await this.connect();
}
this.send(0, {
op: GatewayOpcodes.Identify,
d: {
@ -132,15 +117,19 @@ export class Shard {
});
}
reconnect() {
this.heartbeater.stopHeartbeating()
this.disconnect();
return this.connect();
}
resume() {
this.logger.fatal(`[Shard #${this.id}]`, "Resuming");
this.state = ShardState.Resuming;
const data = {
seq: this.data.resumeSeq!,
session_id: this.data.session_id!,
token: `Bot ${this.options.token}`,
};
console.log({ data });
return this.send(0, { d: data, op: GatewayOpcodes.Resume });
}
@ -151,9 +140,6 @@ export class Shard {
* in simpler terms, do not use where we don't want buckets
*/
async send<T extends GatewaySendPayload = GatewaySendPayload>(priority: number, message: T) {
// biome-ignore lint/style/noArguments: <explanation>
// biome-ignore lint/correctness/noUndeclaredVariables: <explanation>
this.logger.fatal(`[Shard #${this.id}]`, "Send", ...arguments);
// Before acquiring a token from the bucket, check whether the shard is currently offline or not.
// Else bucket and token wait time just get wasted.
await this.checkOffline(priority);
@ -197,30 +183,19 @@ export class Shard {
this.heartbeater.onpacket(packet);
switch (packet.op) {
case GatewayOpcodes.Hello:
if (this.data.session_id) {
await this.resume();
} else {
// await this.identify(true);
}
break;
case GatewayOpcodes.Reconnect:
this.disconnect();
await this.connect();
// await this.resume();
this.reconnect();
break;
case GatewayOpcodes.InvalidSession: {
const resumable = packet.d as boolean;
const resumable = packet.d && this.data.session_id
// We need to wait for a random amount of time between 1 and 5
// Reference: https://discord.com/developers/docs/topics/gateway#resuming
// el delay es el tipico timoeut promise, hazmelo pls
//yo con un import { setTimeout as delay } from 'node:timers/promises'; en la mochila
await delay(Math.floor((Math.random() * 4 + 1) * 1000));
if (!resumable) {
this.data.resumeSeq = 0;
this.data.session_id = undefined;
await this.identify(true);
await this.connect();
break;
}
await this.resume();
@ -254,8 +229,6 @@ export class Shard {
}
disconnect() {
// biome-ignore lint/style/noArguments: <explanation>
// biome-ignore lint/correctness/noUndeclaredVariables: <explanation>
this.logger.info(`[Shard #${this.id}]`, "Disconnect", ...arguments);
this.close(ShardSocketCloseCodes.Shutdown, "Shard down request");
this.state = ShardState.Offline;
@ -281,7 +254,8 @@ export class Shard {
this.logger.debug(`[Shard #${this.id}] Gateway connection closing requiring re-identify. Code: ${close.code}`);
this.state = ShardState.Identifying;
return this.identify();
this.connect();
break;
case GatewayCloseCodes.AuthenticationFailed:
case GatewayCloseCodes.InvalidShard:
case GatewayCloseCodes.ShardingRequired:
@ -293,8 +267,7 @@ export class Shard {
throw new Error(close.reason || "Discord gave no reason! GG! You broke Discord!");
// Gateway connection closes on which a resume is allowed.
default:
console.log(close.code);
this.logger.info(`[Shard #${this.id}] closed shard #${this.id}. Resuming...`);
this.logger.info(`[Shard #${this.id}] (${close.code}) closed shard #${this.id}. Resuming...`);
this.state = ShardState.Resuming;
this.disconnect();

View File

@ -72,7 +72,7 @@ export class ShardManager extends Collection<number, Shard> {
for (const shard of bucket) {
if (!shard) break;
this.logger.info(`${shard.id} add to connect queue`);
await this.connectQueue.push(shard.identify.bind(shard, false));
await this.connectQueue.push(shard.connect.bind(shard));
}
}
}