fix: harden container status polling after idle

This commit is contained in:
JOJO 2025-12-16 20:32:24 +08:00
parent 7f7a7e9f94
commit 599f331c35

View File

@ -76,6 +76,9 @@ export const useResourceStore = defineStore('resource', {
up_bps: null
} as ContainerNetRate,
lastContainerSample: null as ContainerSample | null,
containerStatsInFlight: false,
containerStatsFailCount: 0,
containerStatsIntervalMs: 500,
containerStatsTimer: null as ReturnType<typeof setInterval> | null,
projectStorageTimer: null as ReturnType<typeof setInterval> | null,
projectStorageInFlight: false,
@ -202,33 +205,71 @@ export const useResourceStore = defineStore('resource', {
this.containerStatus = status;
},
async pollContainerStats() {
if (typeof document !== 'undefined' && document.hidden) {
return;
}
if (this.containerStatsInFlight) {
return;
}
this.containerStatsInFlight = true;
const controller = typeof AbortController !== 'undefined' ? new AbortController() : null;
const timeoutId = controller ? window.setTimeout(() => controller.abort(), 4000) : null;
try {
const response = await fetch('/api/container-status');
const response = await fetch('/api/container-status', {
signal: controller?.signal
});
if (!response.ok) {
return;
throw new Error(`http-${response.status}`);
}
const data = await response.json();
if (data.success) {
this.updateContainerStatus(data.data || null);
}
this.containerStatsFailCount = 0;
if (this.containerStatsIntervalMs > 500) {
this._restartContainerStatsTimer(500);
}
} catch (error) {
console.warn('获取容器状态异常:', error);
this.containerStatsFailCount += 1;
if (this.containerStatsFailCount >= 3) {
const nextInterval = Math.min(this.containerStatsIntervalMs * 2, 10_000);
this._restartContainerStatsTimer(nextInterval);
}
} finally {
this.containerStatsInFlight = false;
if (timeoutId) {
clearTimeout(timeoutId);
}
}
},
startContainerStatsPolling() {
if (this.containerStatsTimer) {
return;
}
this.containerStatsFailCount = 0;
this.containerStatsIntervalMs = 500;
this.pollContainerStats();
this.containerStatsTimer = setInterval(() => {
this.pollContainerStats();
}, 500);
}, this.containerStatsIntervalMs);
},
stopContainerStatsPolling() {
if (this.containerStatsTimer) {
clearInterval(this.containerStatsTimer);
this.containerStatsTimer = null;
}
this.containerStatsInFlight = false;
},
_restartContainerStatsTimer(interval: number) {
if (this.containerStatsTimer) {
clearInterval(this.containerStatsTimer);
this.containerStatsTimer = null;
}
this.containerStatsIntervalMs = interval;
this.containerStatsTimer = setInterval(() => {
this.pollContainerStats();
}, this.containerStatsIntervalMs);
},
async pollProjectStorage() {
if (this.projectStorageInFlight) {