fix: prevent stale update log polling

This commit is contained in:
hy 2026-04-22 20:10:04 +08:00
parent 2286988b90
commit d0443e59be

View File

@ -117,6 +117,10 @@ createApp({
},
result: null,
pollTimer: null,
statusRequestInFlight: false,
statusRequestSeq: 0,
statusAppliedSeq: 0,
requestEpoch: 0,
},
restartOps: {
loading: false,
@ -455,7 +459,17 @@ createApp({
return;
}
// 轮询只保留一个在途请求,避免旧响应晚到后把新日志覆盖掉。
if (this.updateOps.statusRequestInFlight) {
return;
}
const wasRunning = this.updateOps.running;
const requestSeq = this.updateOps.statusRequestSeq + 1;
const requestEpoch = this.updateOps.requestEpoch;
this.updateOps.statusRequestSeq = requestSeq;
this.updateOps.statusRequestInFlight = true;
try {
const query = new URLSearchParams({ id: operationId });
const response = await fetch(`/api/ops/update-status?${query.toString()}`, { cache: "no-store" });
@ -464,6 +478,21 @@ createApp({
throw new Error(payload.error || `HTTP ${response.status}`);
}
// 新任务已经开始时,直接丢掉旧任务轮询结果。
if (requestEpoch !== this.updateOps.requestEpoch) {
return;
}
if (this.updateOps.operationId && this.updateOps.operationId !== operationId) {
return;
}
// 保护日志顺序,旧轮询结果不能回退页面状态。
if (requestSeq < this.updateOps.statusAppliedSeq) {
return;
}
this.updateOps.statusAppliedSeq = requestSeq;
this.applyUpdateOperation(payload.operation || {});
if (!this.updateOps.running) {
@ -475,6 +504,14 @@ createApp({
}
}
} catch (error) {
if (requestEpoch !== this.updateOps.requestEpoch) {
return;
}
if (this.updateOps.operationId && this.updateOps.operationId !== operationId) {
return;
}
const errorMessage = error instanceof Error ? error.message : String(error);
const notFound = errorMessage.includes("update operation not found") || errorMessage.includes("HTTP 404");
@ -499,6 +536,10 @@ createApp({
this.updateOps.message = "更新状态查询失败";
}
this.updateOps.error = errorMessage;
} finally {
if (requestEpoch === this.updateOps.requestEpoch && this.updateOps.statusRequestSeq === requestSeq) {
this.updateOps.statusRequestInFlight = false;
}
}
},
applyRefreshTimer() {
@ -848,6 +889,9 @@ createApp({
}
this.stopUpdatePolling();
this.updateOps.requestEpoch += 1;
this.updateOps.statusRequestInFlight = false;
this.updateOps.statusAppliedSeq = 0;
this.updateOps.running = true;
this.updateOps.error = "";
this.updateOps.message = "已提交更新任务,等待开始执行";