From 94d24bac354780c94501a487fb4679269abd9f00 Mon Sep 17 00:00:00 2001 From: M1 Date: Tue, 17 Mar 2026 07:12:48 +0400 Subject: [PATCH] fix: fetch sparkline/chart immediately on SSE ping, no debounce delay --- apps/web/src/views/detail.ejs | 22 ++++++++++------------ apps/web/src/views/home.ejs | 26 ++++++++++---------------- 2 files changed, 20 insertions(+), 28 deletions(-) diff --git a/apps/web/src/views/detail.ejs b/apps/web/src/views/detail.ejs index 1943b8c..298c764 100644 --- a/apps/web/src/views/detail.ejs +++ b/apps/web/src/views/detail.ejs @@ -265,18 +265,16 @@ } }); - // SSE: account stream filtered to this monitor — refresh chart on ping - let _chartRefreshTimer = null; - watchAccount((ping) => { - if (ping.monitor_id !== monitorId) return; - if (_chartRefreshTimer) return; - _chartRefreshTimer = setTimeout(async () => { - _chartRefreshTimer = null; - try { - const res = await fetch(`/dashboard/monitors/${monitorId}/chart`, { credentials: 'same-origin' }); - if (res.ok) document.getElementById('latency-chart').innerHTML = await res.text(); - } catch {} - }, 5000); + // SSE: on ping for this monitor, fetch fresh chart + let _fetchingChart = false; + watchAccount(async (ping) => { + if (ping.monitor_id !== monitorId || _fetchingChart) return; + _fetchingChart = true; + try { + const res = await fetch(`/dashboard/monitors/${monitorId}/chart`, { credentials: 'same-origin' }); + if (res.ok) document.getElementById('latency-chart').innerHTML = await res.text(); + } catch {} + _fetchingChart = false; }); diff --git a/apps/web/src/views/home.ejs b/apps/web/src/views/home.ejs index 9f3e1a9..dbdacb2 100644 --- a/apps/web/src/views/home.ejs +++ b/apps/web/src/views/home.ejs @@ -75,25 +75,19 @@ } catch {} }, 30000); - // Sparkline refresh — debounced per monitor (at most once per 5s) - const _sparklineTimers = {}; - function scheduleSparklineRefresh(mid, sparkEl) { - if (_sparklineTimers[mid]) return; - _sparklineTimers[mid] = setTimeout(async () => { - delete _sparklineTimers[mid]; - try { - const res = await fetch(`/dashboard/monitors/${mid}/sparkline`, { credentials: 'same-origin' }); - if (res.ok) sparkEl.innerHTML = await res.text(); - } catch {} - }, 5000); - } - - // SSE: single account stream — refresh sparkline for the relevant card on each ping - watchAccount((ping) => { + // SSE: on each ping, fetch fresh sparkline for that monitor + const _fetchingSparkline = new Set(); + watchAccount(async (ping) => { const card = document.querySelector(`[data-monitor-id="${ping.monitor_id}"]`); if (!card) return; const sparkEl = card.querySelector('.stat-sparkline'); - if (sparkEl) scheduleSparklineRefresh(ping.monitor_id, sparkEl); + if (!sparkEl || _fetchingSparkline.has(ping.monitor_id)) return; + _fetchingSparkline.add(ping.monitor_id); + try { + const res = await fetch(`/dashboard/monitors/${ping.monitor_id}/sparkline`, { credentials: 'same-origin' }); + if (res.ok) sparkEl.innerHTML = await res.text(); + } catch {} + _fetchingSparkline.delete(ping.monitor_id); });