Skip to content

Commit 3177c47

Browse files
committed
stop websocket traffic on idle
1 parent a6defe5 commit 3177c47

1 file changed

Lines changed: 38 additions & 5 deletions

File tree

‎src/static/js/dashboard.js‎

Lines changed: 38 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ const state = {
4646
checkProcessIdOnNextMessage: false,
4747
// Idle state tracking
4848
isIdle: false,
49+
intentionalDisconnect: false,
4950
idleTimeoutMinutes: 20,
5051
secondsUntilIdle: -1,
5152
// Track processed event keys to avoid duplicate server event display
@@ -217,10 +218,8 @@ function initializeWebSocket() {
217218
wsDisconnectMessageTimeout = null;
218219
}
219220

220-
// Don't overwrite 'Idle' status if app is currently idle
221-
if (!state.isIdle) {
222-
updateConnectionStatus('connected', 'Connected');
223-
}
221+
state.intentionalDisconnect = false;
222+
updateConnectionStatus('connected', 'Connected');
224223

225224
// Log reconnection if we were previously connected
226225
if (wsDisconnectTime) {
@@ -241,6 +240,11 @@ function initializeWebSocket() {
241240
};
242241

243242
state.wsConnection.onclose = (event) => {
243+
// If we intentionally disconnected for idle, don't reconnect or update status
244+
if (state.intentionalDisconnect) {
245+
return;
246+
}
247+
244248
updateConnectionStatus('disconnected', 'Disconnected');
245249

246250
// Record disconnect time if not already set
@@ -282,6 +286,17 @@ function updateConnectionStatus(status, text) {
282286
}
283287
}
284288

289+
/**
290+
* Ensures the WebSocket connection is open. If disconnected (e.g., after idle),
291+
* reconnects immediately. Called by simulation functions to wake the connection.
292+
*/
293+
function ensureWebSocket() {
294+
if (!state.wsConnection || state.wsConnection.readyState === WebSocket.CLOSED || state.wsConnection.readyState === WebSocket.CLOSING) {
295+
state.intentionalDisconnect = false;
296+
initializeWebSocket();
297+
}
298+
}
299+
285300
// ==========================================================================
286301
// Metrics Handling
287302
// ==========================================================================
@@ -357,11 +372,16 @@ function handleMetricsUpdate(message) {
357372
state.isIdle = idleData.is_idle;
358373
state.secondsUntilIdle = idleData.seconds_until_idle || -1;
359374

360-
// Transition to idle
375+
// Transition to idle - stop probes and disconnect WebSocket
361376
if (idleData.is_idle && !wasIdle) {
362377
stopLatencyProbe();
363378
updateIdleDisplay(true);
364379
logEvent('warning', 'Application going idle, no health probes being sent. There will be gaps in diagnostics and logs.');
380+
// Intentionally disconnect WebSocket to prevent reconnect cycle flicker
381+
state.intentionalDisconnect = true;
382+
if (state.wsConnection) {
383+
state.wsConnection.close();
384+
}
365385
}
366386
// Transition from idle
367387
else if (!idleData.is_idle && wasIdle) {
@@ -1107,6 +1127,7 @@ function getServerEventIcon(eventType) {
11071127
// ==========================================================================
11081128

11091129
async function triggerCpuStress() {
1130+
ensureWebSocket();
11101131
const duration = parseInt(document.getElementById('cpuDuration').value) || 30;
11111132
const level = document.getElementById('cpuLevel').value || 'high';
11121133

@@ -1135,6 +1156,7 @@ async function triggerCpuStress() {
11351156
}
11361157

11371158
async function stopCpuStress() {
1159+
ensureWebSocket();
11381160
try {
11391161
// Server broadcasts stop event via WebSocket
11401162
const response = await fetch(`${CONFIG.apiBaseUrl}/cpu/stop`, { method: 'POST' });
@@ -1149,6 +1171,7 @@ async function stopCpuStress() {
11491171
}
11501172

11511173
async function allocateMemory() {
1174+
ensureWebSocket();
11521175
const sizeMb = parseInt(document.getElementById('memorySize').value) || 100;
11531176

11541177
try {
@@ -1169,6 +1192,7 @@ async function allocateMemory() {
11691192
}
11701193

11711194
async function releaseMemory() {
1195+
ensureWebSocket();
11721196
try {
11731197
// Server broadcasts release event via WebSocket
11741198
const response = await fetch(`${CONFIG.apiBaseUrl}/memory/release-all`, { method: 'POST' });
@@ -1183,6 +1207,7 @@ async function releaseMemory() {
11831207
}
11841208

11851209
async function triggerThreadBlock() {
1210+
ensureWebSocket();
11861211
const delay = parseFloat(document.getElementById('threadDelay').value) || 10;
11871212
const count = parseInt(document.getElementById('threadConcurrent').value) || 10;
11881213

@@ -1208,6 +1233,7 @@ async function triggerThreadBlock() {
12081233
}
12091234

12101235
async function stopThreadBlock() {
1236+
ensureWebSocket();
12111237
try {
12121238
// Server logs stop event via WebSocket; no client-side duplicate needed
12131239
const response = await fetch(`${CONFIG.apiBaseUrl}/blocking/stop`, { method: 'POST' });
@@ -1222,6 +1248,7 @@ async function stopThreadBlock() {
12221248
}
12231249

12241250
async function startSlowRequests() {
1251+
ensureWebSocket();
12251252
const duration = parseInt(document.getElementById('slowRequestDuration').value) || 25;
12261253
const interval = parseFloat(document.getElementById('slowRequestInterval').value) || 2;
12271254
const maxRequests = parseInt(document.getElementById('slowRequestMax').value) || 10;
@@ -1248,6 +1275,7 @@ async function startSlowRequests() {
12481275
}
12491276

12501277
async function stopSlowRequests() {
1278+
ensureWebSocket();
12511279
try {
12521280
// Server broadcasts stop event via WebSocket
12531281
const response = await fetch(`${CONFIG.apiBaseUrl}/slow/stop`, { method: 'POST' });
@@ -1262,6 +1290,7 @@ async function stopSlowRequests() {
12621290
}
12631291

12641292
async function generateFailedRequests() {
1293+
ensureWebSocket();
12651294
const count = parseInt(document.getElementById('failedRequestCount').value) || 10;
12661295

12671296
try {
@@ -1282,6 +1311,7 @@ async function generateFailedRequests() {
12821311
}
12831312

12841313
async function triggerCrash() {
1314+
ensureWebSocket();
12851315
const crashType = document.getElementById('crashType').value;
12861316
const crashTypeDisplay = crashType.charAt(0).toUpperCase() + crashType.slice(1);
12871317

@@ -1650,6 +1680,9 @@ document.addEventListener('DOMContentLoaded', async function() {
16501680
initSimulationIdCopyHandlers();
16511681
await fetchConfig();
16521682

1683+
// Wake the server if it's idle (page load counts as activity)
1684+
await recordActivity('page_load');
1685+
16531686
// Connect to WebSocket
16541687
initializeWebSocket();
16551688

0 commit comments

Comments
 (0)