use setTimeout for heartbeat in favour of first random interval

This commit is contained in:
ITOH
2021-04-15 10:40:07 +02:00
parent 81a3bc3c26
commit 28ff1574d8
4 changed files with 44 additions and 28 deletions
+40 -24
View File
@@ -14,28 +14,44 @@ export function heartbeat(shardId: number, interval: number) {
shard.heartbeat.lastSentAt = Date.now(); shard.heartbeat.lastSentAt = Date.now();
shard.heartbeat.interval = interval; shard.heartbeat.interval = interval;
shard.heartbeat.intervalId = setInterval(() => { // First heartbeat should be sent bevore
ws.log("DEBUG", `Running setInterval in heartbeat file.`); shard.heartbeat.timeoutId = setTimeout(
const currentShard = ws.shards.get(shardId); () => sendHeartbeat(shardId),
if (!currentShard) return; Math.floor(shard.heartbeat.interval * Math.random()),
);
ws.log("HEARTBEATING", { shardId, shard: currentShard }); }
if ( function sendHeartbeat(shardId: number) {
currentShard.ws.readyState === WebSocket.CLOSED || ws.log("DEBUG", `Running setInterval in heartbeat file.`);
!currentShard.heartbeat.keepAlive const currentShard = ws.shards.get(shardId);
) { if (!currentShard) return;
ws.log("HEARTBEATING_CLOSED", { shardId, shard: currentShard });
ws.log("HEARTBEATING", { shardId, shard: currentShard });
// STOP THE HEARTBEAT
return clearInterval(currentShard.heartbeat.intervalId); if (
} currentShard.ws.readyState === WebSocket.CLOSED ||
!currentShard.heartbeat.keepAlive
if (currentShard.ws.readyState !== WebSocket.OPEN) return; ) {
ws.log("HEARTBEATING_CLOSED", { shardId, shard: currentShard });
currentShard.ws.send(JSON.stringify({
op: DiscordGatewayOpcodes.Heartbeat, // STOP THE HEARTBEAT
d: currentShard.previousSequenceNumber, return;
})); }
}, interval);
if (currentShard.ws.readyState !== WebSocket.OPEN) {
currentShard.heartbeat.timeoutId = setTimeout(
() => sendHeartbeat(shardId),
currentShard.heartbeat.interval,
);
}
currentShard.ws.send(JSON.stringify({
op: DiscordGatewayOpcodes.Heartbeat,
d: currentShard.previousSequenceNumber,
}));
currentShard.heartbeat.timeoutId = setTimeout(
() => sendHeartbeat(shardId),
currentShard.heartbeat.interval,
);
} }
+2 -2
View File
@@ -7,7 +7,7 @@ export async function identify(shardId: number, maxShards: number) {
// Need to clear the old heartbeat interval // Need to clear the old heartbeat interval
const oldShard = ws.shards.get(shardId); const oldShard = ws.shards.get(shardId);
if (oldShard) { if (oldShard) {
clearInterval(oldShard.heartbeat.intervalId); clearTimeout(oldShard.heartbeat.timeoutId);
} }
// CREATE A SHARD // CREATE A SHARD
@@ -29,7 +29,7 @@ export async function identify(shardId: number, maxShards: number) {
acknowledged: false, acknowledged: false,
keepAlive: false, keepAlive: false,
interval: 0, interval: 0,
intervalId: 0, timeoutId: 0,
}, },
queue: [], queue: [],
processingQueue: false, processingQueue: false,
+1 -1
View File
@@ -138,7 +138,7 @@ export interface DiscordenoShard {
/** The interval between heartbeats requested by discord. */ /** The interval between heartbeats requested by discord. */
interval: number; interval: number;
/** The id of the interval, useful for stopping the interval if ws closed. */ /** The id of the interval, useful for stopping the interval if ws closed. */
intervalId: number; timeoutId: number;
}; };
/** The items/requestst that are in queue to be sent to this shard websocket. */ /** The items/requestst that are in queue to be sent to this shard websocket. */
queue: WebSocketRequest[]; queue: WebSocketRequest[];
+1 -1
View File
@@ -7,7 +7,7 @@ Deno.test({
name: "[ws] Close all shards manually.", name: "[ws] Close all shards manually.",
async fn() { async fn() {
ws.shards.forEach((shard) => { ws.shards.forEach((shard) => {
clearInterval(shard.heartbeat.intervalId); clearTimeout(shard.heartbeat.timeoutId);
shard.ws.close(3064, "Discordeno Testing Finished! Do Not RESUME!"); shard.ws.close(3064, "Discordeno Testing Finished! Do Not RESUME!");
}); });