mirror of
https://github.com/cpvalente/ontime.git
synced 2026-08-20 14:39:06 +00:00
refactor: improve connection handling
- only invalidate caches on reconnect - add jitter to avoid overwhelming server and allow cache to stabilise - prevent multiple reconnect timers
This commit is contained in:
committed by
Carlos Valente
parent
9e8cb1c755
commit
aec6673b07
@@ -38,7 +38,13 @@ import { patchRuntime, patchRuntimeProperty } from '../stores/runtime';
|
|||||||
|
|
||||||
let websocket: WebSocket | null = null;
|
let websocket: WebSocket | null = null;
|
||||||
let reconnectTimeout: NodeJS.Timeout | null = null;
|
let reconnectTimeout: NodeJS.Timeout | null = null;
|
||||||
const reconnectInterval = 1000;
|
const socketConfig = {
|
||||||
|
reconnectBaseInterval: 1000, // 1 second
|
||||||
|
reconnectMaxInterval: 30000, // 30 seconds
|
||||||
|
reconnectMinInterval: 500, // 0.5 seconds
|
||||||
|
reconnectJitter: 0.25,
|
||||||
|
offlineAttemptsThreshold: 2, // when we consider the client disconnected
|
||||||
|
} as const;
|
||||||
|
|
||||||
export let hasConnected = false;
|
export let hasConnected = false;
|
||||||
export let reconnectAttempts = 0;
|
export let reconnectAttempts = 0;
|
||||||
@@ -49,7 +55,11 @@ export const connectSocket = () => {
|
|||||||
const preferredClientName = getClientName();
|
const preferredClientName = getClientName();
|
||||||
|
|
||||||
websocket.onopen = () => {
|
websocket.onopen = () => {
|
||||||
clearTimeout(reconnectTimeout as NodeJS.Timeout);
|
const isReconnect = hasConnected;
|
||||||
|
if (reconnectTimeout) {
|
||||||
|
clearTimeout(reconnectTimeout);
|
||||||
|
reconnectTimeout = null;
|
||||||
|
}
|
||||||
hasConnected = true;
|
hasConnected = true;
|
||||||
reconnectAttempts = 0;
|
reconnectAttempts = 0;
|
||||||
|
|
||||||
@@ -59,24 +69,38 @@ export const connectSocket = () => {
|
|||||||
path: window.location.pathname + window.location.search,
|
path: window.location.pathname + window.location.search,
|
||||||
name: preferredClientName,
|
name: preferredClientName,
|
||||||
});
|
});
|
||||||
invalidateAllCaches(); // assume all data to be stale after a reconnect
|
|
||||||
|
if (isReconnect) {
|
||||||
|
invalidateAllCaches();
|
||||||
|
}
|
||||||
setOnlineStatus(true);
|
setOnlineStatus(true);
|
||||||
};
|
};
|
||||||
|
|
||||||
websocket.onclose = () => {
|
websocket.onclose = () => {
|
||||||
console.warn('WebSocket disconnected');
|
console.warn('WebSocket disconnected');
|
||||||
|
if (reconnectTimeout) {
|
||||||
|
clearTimeout(reconnectTimeout);
|
||||||
|
reconnectTimeout = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const exponentialDelay = Math.min(
|
||||||
|
socketConfig.reconnectBaseInterval * 2 ** reconnectAttempts,
|
||||||
|
socketConfig.reconnectMaxInterval,
|
||||||
|
);
|
||||||
|
const jitterOffset = exponentialDelay * socketConfig.reconnectJitter * (Math.random() * 2 - 1);
|
||||||
|
const delay = Math.max(socketConfig.reconnectMinInterval, Math.round(exponentialDelay + jitterOffset));
|
||||||
|
|
||||||
// we decide to allows reconnect
|
|
||||||
reconnectTimeout = setTimeout(() => {
|
reconnectTimeout = setTimeout(() => {
|
||||||
if (reconnectAttempts > 2) {
|
reconnectTimeout = null;
|
||||||
|
if (reconnectAttempts > socketConfig.offlineAttemptsThreshold) {
|
||||||
setOnlineStatus(false);
|
setOnlineStatus(false);
|
||||||
}
|
}
|
||||||
console.warn('WebSocket: attempting reconnect');
|
console.warn(`WebSocket: reconnecting now (#${reconnectAttempts + 1}, waited ${delay}ms)`);
|
||||||
if (websocket && websocket.readyState === WebSocket.CLOSED) {
|
if (websocket && websocket.readyState === WebSocket.CLOSED) {
|
||||||
reconnectAttempts += 1;
|
reconnectAttempts += 1;
|
||||||
connectSocket();
|
connectSocket();
|
||||||
}
|
}
|
||||||
}, reconnectInterval);
|
}, delay);
|
||||||
};
|
};
|
||||||
|
|
||||||
websocket.onerror = (error) => {
|
websocket.onerror = (error) => {
|
||||||
|
|||||||
Reference in New Issue
Block a user