Bring Back Realtime Table Stats
Release rolling / release (push) Successful in 7m55s

This commit is contained in:
Raven Scott
2026-08-04 22:37:41 -04:00
parent c5015a66e8
commit 637c386e33
12 changed files with 689 additions and 636 deletions
+91
View File
@@ -125,6 +125,8 @@ manager.on('disconnect', (conn) => {
}
if (!manager.active?.connected) {
updateHealthBadge(null);
lastStatsInterestSent = null;
lastStatsInterestPeerId = null;
}
refreshFleetIfVisible();
if (isBootRestoring) return;
@@ -133,6 +135,8 @@ manager.on('disconnect', (conn) => {
if (!hasActiveConnection()) {
resetContainerList();
stopStatsInterval();
lastStatsInterestSent = null;
lastStatsInterestPeerId = null;
if (typeof manager.isReconnecting === 'function' && manager.isReconnecting()) {
// reconnecting banner is driven by 'reconnecting' events
return;
@@ -160,6 +164,26 @@ manager.on('connect', (conn) => {
{ latency: conn.latency, docker: conn.dockerHealth, status: conn.healthStatus },
conn
);
// Re-declare view interest after (re)connect so stats streams resume if needed
lastStatsInterestSent = null;
lastStatsInterestPeerId = null;
try {
syncStatsInterest({ force: true });
} catch {
// ignore
}
}
});
manager.on('active', (conn) => {
// Switching fleet peer: re-send interest to the new active host
lastStatsInterestSent = null;
lastStatsInterestPeerId = null;
if (conn?.connected) {
try {
syncStatsInterest({ force: true });
} catch {
// ignore
}
}
});
/** Throttle reconnect notices (standard mode only) */
@@ -419,6 +443,66 @@ function startStatsInterval() {
stopStatsInterval();
}
/**
* Views that show live per-container CPU/memory (table or dashboard KPIs).
* Server only opens Docker stats streams while 1 peer reports interest.
*/
const STATS_INTEREST_VIEWS = new Set(['containers', 'dashboard', 'container-details']);
/** @type {boolean|null} last interest sent for active peer (avoid spam) */
let lastStatsInterestSent = null;
/** @type {string|null} peer id we last told */
let lastStatsInterestPeerId = null;
/**
* Tell the active peer whether this UI needs live fleet stats.
* Call on view change and after connect. Leaving Containers/Dashboard tears
* down server-side Docker stats streams for this client.
* @param {{ force?: boolean }} [opts]
*/
function syncStatsInterest(opts = {}) {
const force = opts.force === true;
const conn = manager.active;
if (!conn?.connected) {
lastStatsInterestSent = null;
lastStatsInterestPeerId = null;
return;
}
const view =
typeof currentView === 'string'
? currentView
: typeof window !== 'undefined' && typeof window.currentView === 'string'
? window.currentView
: '';
const want = STATS_INTEREST_VIEWS.has(view);
if (
!force &&
lastStatsInterestSent === want &&
lastStatsInterestPeerId === conn.id
) {
return;
}
lastStatsInterestSent = want;
lastStatsInterestPeerId = conn.id;
try {
conn
.request(Methods.setStatsInterest || 'setStatsInterest', {
active: want,
view: view || undefined,
})
.catch(() => {
// older servers may lack the method — ignore
lastStatsInterestSent = null;
});
} catch {
lastStatsInterestSent = null;
}
}
if (typeof window !== 'undefined') {
window.syncStatsInterest = syncStatsInterest;
}
// Utility functions are now imported from uiUtils.js
@@ -1384,6 +1468,13 @@ function navigateToView(viewName, opts = {}) {
// Expose for auto-refresh poller
if (typeof window !== 'undefined') window.currentView = viewName;
// Demand-driven fleet stats: only collect while on Containers / Dashboard / details
try {
syncStatsInterest();
} catch {
// ignore
}
// Drop live streams / PTYs when leaving container details
if (leavingDetails) {
if (typeof stopDetailsLogs === 'function') stopDetailsLogs();