Skip to content

Commit 150a8e5

Browse files
authored
Merge pull request #20 from airframesio/copilot/sub-pr-4-again
Implement exponential backoff for WebSocket reconnection
2 parents 0c420c2 + 75e27cf commit 150a8e5

2 files changed

Lines changed: 39 additions & 21 deletions

File tree

cmd/web/script.js

Lines changed: 38 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -188,9 +188,9 @@ function connectWebSocket() {
188188
document.getElementById('status').classList.remove('disconnected');
189189
document.getElementById('status-text').textContent = 'Connected to live updates';
190190

191-
// Clear reconnect interval if exists
191+
// Clear reconnect timeout if exists
192192
if (wsReconnectInterval) {
193-
clearInterval(wsReconnectInterval);
193+
clearTimeout(wsReconnectInterval);
194194
wsReconnectInterval = null;
195195
}
196196
};
@@ -225,25 +225,43 @@ function connectWebSocket() {
225225
document.getElementById('status-text').textContent = 'Connection lost - attempting to reconnect...';
226226
}
227227

228+
// Clear any existing reconnection timer to prevent memory leaks
229+
if (wsReconnectInterval) {
230+
clearTimeout(wsReconnectInterval);
231+
wsReconnectInterval = null;
232+
}
233+
228234
// Set up reconnection with exponential backoff
229-
if (!wsReconnectInterval) {
230-
let reconnectAttempts = 0;
231-
wsReconnectInterval = setInterval(() => {
232-
reconnectAttempts++;
233-
const maxAttempts = 30;
234-
235-
if (reconnectAttempts > maxAttempts) {
236-
clearInterval(wsReconnectInterval);
237-
wsReconnectInterval = null;
238-
document.getElementById('status-text').textContent = 'Connection failed - please refresh the page';
239-
return;
240-
}
235+
let reconnectAttempts = 0;
236+
let delay = 1000; // Start with 1 second
237+
238+
const attemptReconnect = () => {
239+
reconnectAttempts++;
240+
const maxAttempts = 30;
241+
242+
if (reconnectAttempts > maxAttempts) {
243+
wsReconnectInterval = null;
244+
document.getElementById('status-text').textContent = 'Connection failed - please refresh the page';
245+
return;
246+
}
241247

242-
console.log('Reconnect attempt ' + reconnectAttempts + '/' + maxAttempts);
243-
document.getElementById('status-text').textContent = 'Reconnecting (' + reconnectAttempts + '/' + maxAttempts + ')...';
244-
connectWebSocket();
245-
}, 2000);
246-
}
248+
console.log('Reconnect attempt ' + reconnectAttempts + '/' + maxAttempts + ' (delay: ' + delay + 'ms)');
249+
document.getElementById('status-text').textContent = 'Reconnecting (' + reconnectAttempts + '/' + maxAttempts + ')...';
250+
251+
// Close existing WebSocket if it exists to avoid resource leaks
252+
if (ws) {
253+
ws.onclose = null; // Remove handler to prevent triggering another reconnection
254+
ws.close();
255+
}
256+
257+
connectWebSocket();
258+
259+
// Double the delay for next attempt, cap at 30 seconds
260+
delay = Math.min(delay * 2, 30000);
261+
wsReconnectInterval = setTimeout(attemptReconnect, delay);
262+
};
263+
264+
wsReconnectInterval = setTimeout(attemptReconnect, delay);
247265
};
248266
}
249267

@@ -782,6 +800,6 @@ window.addEventListener('beforeunload', () => {
782800
ws.close();
783801
}
784802
if (wsReconnectInterval) {
785-
clearInterval(wsReconnectInterval);
803+
clearTimeout(wsReconnectInterval);
786804
}
787805
});

0 commit comments

Comments
 (0)