From a353faaa714e01012959aa3b76e672fa8e837bfd Mon Sep 17 00:00:00 2001 From: sagitchu Date: Sun, 22 Mar 2026 19:05:31 +0800 Subject: [PATCH] chore: release 2.1.9-rc3 (fix service monitor stale detection) --- AGENTS.md | 2 +- vite-frontend/src/pages/node/monitor-view.tsx | 22 ++++++++++++++++++- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 5a5a48d..cff2a9d 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -3,7 +3,7 @@ **Generated:** Sun Mar 22 2026 **Commit:** 8ebde9d **Branch:** main -**Tag:** 2.1.9-beta14 +**Tag:** 2.1.9-rc3 ## OVERVIEW FLVX (formerly Flux Panel) is a traffic forwarding management system built on a forked GOST v3 stack. It ships as a Go-based admin API (SQLite/PostgreSQL) + Vite/React UI + Go forwarding agent, with optional mobile WebView wrappers. diff --git a/vite-frontend/src/pages/node/monitor-view.tsx b/vite-frontend/src/pages/node/monitor-view.tsx index 88cd7fe..42ae797 100644 --- a/vite-frontend/src/pages/node/monitor-view.tsx +++ b/vite-frontend/src/pages/node/monitor-view.tsx @@ -794,6 +794,20 @@ export function MonitorView({ nodeMap, viewMode = "grid" }: MonitorViewProps) { void loadResultsForModal(); }, [resultsModalOpen, resultsMonitorId, resultsLimit, loadResultsForModal]); + // Auto-load results for the resolved default monitor when entering detail view + useEffect(() => { + if (!detailNodeId) return; + if (activeServiceMonitorId) return; // user already selected one + // Find the first monitor belonging to this node (or panel-level) + const firstMonitor = serviceMonitors.find( + (m) => m.nodeId === detailNodeId || m.nodeId === 0, + ); + if (firstMonitor && (!monitorResults[firstMonitor.id] || monitorResults[firstMonitor.id].length <= 1)) { + void loadMonitorResults(firstMonitor.id, { rangeMs: serviceMonitorRangeMs }); + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [detailNodeId, serviceMonitors]); + // Reload results for the active service monitor chart when time range changes useEffect(() => { if (!activeServiceMonitorId) return; @@ -1023,6 +1037,11 @@ export function MonitorView({ nodeMap, viewMode = "grid" }: MonitorViewProps) { [resolvedServiceMonitorLimits.defaultIntervalSec, resolvedServiceMonitorLimits.minIntervalSec], ); + // Backend batches DB writes every 30s, but latest API reads from in-memory cache. + // The cache timestamp reflects the real check time (every ~1s), so stale detection + // should still allow for the batch report interval + scan jitter. + const SERVICE_MONITOR_REPORT_INTERVAL_MS = 30_000; // matches backend serviceMonitorReportInterval + const isResultStale = useCallback( (monitor: ServiceMonitorApiItem, latestResult: ServiceMonitorResultApiItem | null) => { if (monitor.enabled !== 1) { @@ -1033,8 +1052,9 @@ export function MonitorView({ nodeMap, viewMode = "grid" }: MonitorViewProps) { } const intervalMs = resolveMonitorIntervalSec(monitor) * 1000; + // Budget = batch report interval + one check interval + scan jitter + grace const budgetMs = - intervalMs + resolvedServiceMonitorLimits.checkerScanIntervalSec * 1000 + 5000; + SERVICE_MONITOR_REPORT_INTERVAL_MS + intervalMs + resolvedServiceMonitorLimits.checkerScanIntervalSec * 1000 + 5000; return Date.now() - latestResult.timestamp > budgetMs; },