From 6849707c43bb8b87f9913fc26b6a69d51777d209 Mon Sep 17 00:00:00 2001 From: "Danilo M." Date: Tue, 13 Oct 2026 11:30:07 +0200 Subject: fix(perf): review findings in the service and the panel - The panel loads only while open. Its models are fresh arrays every sample, so a hidden instance rebuilt its rows every 2s for the whole session. - The public IP fetch never kills one already running, and waits 30 minutes from the last attempt, not the last success: a rate-limited or offline fetch was retried every minute. - curl -4, so an IPv6 answer cannot silently stall the VPN check. - CPU load sums only the first eight /proc/stat fields. guest and guest_nice are already inside user and nice, and counting them again read high while VMs ran. - df gets timeout -k; the VRAM scan is not restarted over itself. - The GPU name joins the host constants in Perf.qml. Co-Authored-By: Claude Opus 5.5 --- desktop/island/perf/Perf.qml | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) (limited to 'desktop/island/perf/Perf.qml') diff --git a/desktop/island/perf/Perf.qml b/desktop/island/perf/Perf.qml index c2843f6..3153cec 100644 --- a/desktop/island/perf/Perf.qml +++ b/desktop/island/perf/Perf.qml @@ -36,6 +36,7 @@ Singleton { readonly property var mounts: ["/", "/home", "/data", "/mnt/nfs/Library", "/mnt/nfs/shared"] readonly property string iface: "br0" readonly property real vramTotal: 12 * 1024 * 1024 * 1024 + readonly property string gpuName: "ARC B580" // Conky's table. Ceilings are per sensor: 70C is unremarkable on a CPU // package and alarming on an NVMe. GPU and VRAM are the GPU card's; the @@ -86,15 +87,21 @@ Singleton { return isNaN(v) ? null : v; } + // Measured from the last attempt, not the last success, so a failing + // fetch (rate limited, offline) still waits 30 minutes; and never over + // one already running, which would kill it before it could answer. + property real pubAttempt: 0 function fetchPubip() { - pubProc.running = false; + const now = Date.now() / 1000; + if (pubProc.running || !P.due(root.pub, now, 1800) || now - root.pubAttempt < 1800) return; + root.pubAttempt = now; pubProc.running = true; } onDetailedChanged: { if (detailed) { if (!root.lan) lanProc.running = true; - if (P.due(root.pub, Date.now() / 1000, 1800)) root.fetchPubip(); + root.fetchPubip(); } else { root.cores = []; root.rx = []; @@ -189,8 +196,7 @@ Singleton { if (root.detailed) { if (fanView.path) { fanView.reload(); root.fan = root.num(fanView); } - vramProc.running = false; - vramProc.running = true; + if (!vramProc.running) vramProc.running = true; } } } @@ -247,7 +253,7 @@ Singleton { Process { id: dfProc - command: ["timeout", "5", "/usr/bin/df", "-P", "-B1"].concat(root.mounts) + command: ["timeout", "-k", "2", "5", "/usr/bin/df", "-P", "-B1"].concat(root.mounts) stdout: StdioCollector { onStreamFinished: { const rows = P.df(text); @@ -274,14 +280,14 @@ Singleton { interval: 60000 running: true repeat: true - onTriggered: if (P.due(root.pub, Date.now() / 1000, 1800)) root.fetchPubip() + onTriggered: root.fetchPubip() } // Anything but an IPv4 address (a failure, an error page) leaves the // cache alone: the old value then goes stale rather than mismatching. Process { id: pubProc - command: ["curl", "-fsS", "--max-time", "10", "https://ipinfo.io/ip"] + command: ["curl", "-4fsS", "--max-time", "10", "https://ipinfo.io/ip"] stdout: StdioCollector { onStreamFinished: { const ip = text.trim(); -- cgit v1.2.3