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.interval = interval;
shard.heartbeat.intervalId = setInterval(() => {
ws.log("DEBUG", `Running setInterval in heartbeat file.`);
const currentShard = ws.shards.get(shardId);
if (!currentShard) return;
ws.log("HEARTBEATING", { shardId, shard: currentShard });
if (
currentShard.ws.readyState === WebSocket.CLOSED ||
!currentShard.heartbeat.keepAlive
) {
ws.log("HEARTBEATING_CLOSED", { shardId, shard: currentShard });
// STOP THE HEARTBEAT
return clearInterval(currentShard.heartbeat.intervalId);
}
if (currentShard.ws.readyState !== WebSocket.OPEN) return;
currentShard.ws.send(JSON.stringify({
op: DiscordGatewayOpcodes.Heartbeat,
d: currentShard.previousSequenceNumber,
}));
}, interval);
// First heartbeat should be sent bevore
shard.heartbeat.timeoutId = setTimeout(
() => sendHeartbeat(shardId),
Math.floor(shard.heartbeat.interval * Math.random()),
);
}
function sendHeartbeat(shardId: number) {
ws.log("DEBUG", `Running setInterval in heartbeat file.`);
const currentShard = ws.shards.get(shardId);
if (!currentShard) return;
ws.log("HEARTBEATING", { shardId, shard: currentShard });
if (
currentShard.ws.readyState === WebSocket.CLOSED ||
!currentShard.heartbeat.keepAlive
) {
ws.log("HEARTBEATING_CLOSED", { shardId, shard: currentShard });
// STOP THE HEARTBEAT
return;
}
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
const oldShard = ws.shards.get(shardId);
if (oldShard) {
clearInterval(oldShard.heartbeat.intervalId);
clearTimeout(oldShard.heartbeat.timeoutId);
}
// CREATE A SHARD
@@ -29,7 +29,7 @@ export async function identify(shardId: number, maxShards: number) {
acknowledged: false,
keepAlive: false,
interval: 0,
intervalId: 0,
timeoutId: 0,
},
queue: [],
processingQueue: false,
+1 -1
View File
@@ -138,7 +138,7 @@ export interface DiscordenoShard {
/** The interval between heartbeats requested by discord. */
interval: number;
/** 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. */
queue: WebSocketRequest[];
+1 -1
View File
@@ -7,7 +7,7 @@ Deno.test({
name: "[ws] Close all shards manually.",
async fn() {
ws.shards.forEach((shard) => {
clearInterval(shard.heartbeat.intervalId);
clearTimeout(shard.heartbeat.timeoutId);
shard.ws.close(3064, "Discordeno Testing Finished! Do Not RESUME!");
});