4f13f5c7c0
While the popout is open, poll both status and metrics at a fast cadence (kubeRefreshOpenMs, 3s) instead of 2min/15s, and refresh immediately when it opens — so opening the pill shows fresh data and updates live. Status reverts to the slow 2min pill cadence once closed.
125 lines
4.4 KiB
QML
125 lines
4.4 KiB
QML
pragma Singleton
|
|
|
|
import Quickshell
|
|
import Quickshell.Io
|
|
import QtQuick
|
|
|
|
Singleton {
|
|
id: root
|
|
|
|
property string status: "loading" // "loading" | "ok" | "degraded" | "error" | "stale"
|
|
property var pods: [] // Array of {app, ready, cpuM, memMi}
|
|
property int readyCount: 0
|
|
property int totalCount: 0
|
|
property var quota: null // quota object from metrics script
|
|
property int lastUpdatedSecs: 0 // seconds since last successful status fetch
|
|
|
|
Process {
|
|
id: statusProc
|
|
command: ["bash", Config.scriptsDir + "/k8s-status.sh", Config.kubeNamespace]
|
|
stdout: StdioCollector {
|
|
onStreamFinished: {
|
|
if (this.text.trim() === "") {
|
|
root.status = (root.status === "ok" || root.status === "degraded") ? "stale" : "error";
|
|
return;
|
|
}
|
|
try {
|
|
let data = JSON.parse(this.text);
|
|
// Preserve existing cpuM/memMi from last metrics fetch
|
|
let byApp = {};
|
|
for (let p of root.pods) byApp[p.app] = p;
|
|
root.pods = data.pods.map(p => ({
|
|
app: p.app,
|
|
ready: p.ready,
|
|
cpuM: byApp[p.app]?.cpuM ?? -1,
|
|
memMi: byApp[p.app]?.memMi ?? -1
|
|
}));
|
|
root.readyCount = data.readyCount;
|
|
root.totalCount = data.totalCount;
|
|
root.status = data.pods.every(p => p.ready) ? "ok" : "degraded";
|
|
root.lastUpdatedSecs = 0;
|
|
} catch(e) {
|
|
console.warn("Kubernetes: status parse error:", e);
|
|
root.status = (root.status === "ok" || root.status === "degraded") ? "stale" : "error";
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
Process {
|
|
id: metricsProc
|
|
command: ["bash", Config.scriptsDir + "/k8s-metrics.sh", Config.kubeNamespace]
|
|
stdout: StdioCollector {
|
|
onStreamFinished: {
|
|
if (this.text.trim() === "") return;
|
|
try {
|
|
let data = JSON.parse(this.text);
|
|
let byApp = {};
|
|
for (let m of data.podMetrics) byApp[m.app] = m;
|
|
root.pods = root.pods.map(p => ({
|
|
app: p.app,
|
|
ready: p.ready,
|
|
cpuM: byApp[p.app]?.cpuM ?? -1,
|
|
memMi: byApp[p.app]?.memMi ?? -1
|
|
}));
|
|
root.quota = data.quota;
|
|
} catch(e) {
|
|
console.warn("Kubernetes: metrics parse error:", e);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Ticker: increments lastUpdatedSecs every second (only once status is known)
|
|
Timer {
|
|
interval: 1000
|
|
running: root.status !== "loading"
|
|
repeat: true
|
|
onTriggered: root.lastUpdatedSecs++
|
|
}
|
|
|
|
// Force an immediate refresh (status always; metrics only while the popout is
|
|
// open, where they're shown). Called on pill click and on popout open.
|
|
function refresh() {
|
|
statusProc.running = false; statusProc.running = true;
|
|
if (PopoutState.active === "kubernetes") {
|
|
metricsProc.running = false; metricsProc.running = true;
|
|
}
|
|
}
|
|
|
|
readonly property bool popoutOpen: PopoutState.active === "kubernetes"
|
|
onPopoutOpenChanged: if (popoutOpen) refresh()
|
|
|
|
// Status poller — slow while the popout is closed (just the pill), fast while open.
|
|
Timer {
|
|
interval: root.popoutOpen ? Config.kubeRefreshOpenMs : Config.kubeStatusRefreshMs
|
|
running: Config.kubeEnabled
|
|
repeat: true
|
|
onTriggered: statusProc.running = true
|
|
}
|
|
|
|
// Metrics poller — only while the popout is open, at the fast cadence.
|
|
Timer {
|
|
interval: Config.kubeRefreshOpenMs
|
|
running: Config.kubeEnabled && root.popoutOpen
|
|
repeat: true
|
|
onTriggered: metricsProc.running = true
|
|
}
|
|
|
|
// Staleness check: flip to "stale" if no successful fetch for >60s
|
|
Timer {
|
|
interval: 10000
|
|
running: true
|
|
repeat: true
|
|
onTriggered: {
|
|
if (root.lastUpdatedSecs > 60 && (root.status === "ok" || root.status === "degraded"))
|
|
root.status = "stale";
|
|
}
|
|
}
|
|
|
|
Component.onCompleted: {
|
|
if (Config.kubeEnabled)
|
|
statusProc.running = true;
|
|
}
|
|
}
|