fix: ignore stale SSH update job until running or session start (v0.5.10)
Modal finish only after sawRunning or started_at after sessionOpenedAt, so a previous success no longer closes the window instantly while SAC updater is still running on the host. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
"""Единый источник версии SAC (API, health, логи, OpenAPI)."""
|
||||
|
||||
APP_NAME = "Security Alert Center"
|
||||
APP_VERSION = "0.5.9"
|
||||
APP_VERSION = "0.5.10"
|
||||
APP_VERSION_LABEL = f"{APP_NAME} v.{APP_VERSION}"
|
||||
|
||||
@@ -79,6 +79,7 @@ const props = defineProps<{
|
||||
message: string;
|
||||
output: string;
|
||||
logVisible: boolean;
|
||||
sessionStartedAt: string;
|
||||
}>();
|
||||
|
||||
const emit = defineEmits<{
|
||||
@@ -98,6 +99,28 @@ const autoCloseSec = ref(0);
|
||||
let pollTimer: ReturnType<typeof setInterval> | null = null;
|
||||
let countdownTimer: ReturnType<typeof setInterval> | null = null;
|
||||
let finishedEmitted = false;
|
||||
let sawRunning = false;
|
||||
|
||||
function isTerminalJob(job: HostRemoteActionJobStatus): boolean {
|
||||
const st = (job.status || "").toLowerCase();
|
||||
return st === "success" || st === "failed";
|
||||
}
|
||||
|
||||
function jobStartedAfterSession(job: HostRemoteActionJobStatus): boolean {
|
||||
const started = job.started_at;
|
||||
if (!started) return false;
|
||||
const jobMs = Date.parse(started);
|
||||
const sessionMs = Date.parse(props.sessionStartedAt);
|
||||
if (Number.isNaN(jobMs) || Number.isNaN(sessionMs)) return false;
|
||||
return jobMs >= sessionMs - 3000;
|
||||
}
|
||||
|
||||
function isJobRunning(job: HostRemoteActionJobStatus): boolean {
|
||||
if (job.active) return true;
|
||||
const st = (job.status || "").toLowerCase();
|
||||
if (st === "running") return true;
|
||||
return (job.agent_update_state || "").toLowerCase() === "running";
|
||||
}
|
||||
|
||||
const displayTitle = computed(() => {
|
||||
if (localTitle.value) return localTitle.value;
|
||||
@@ -159,7 +182,14 @@ async function pollJobOnce() {
|
||||
if (out) polledOutput.value = out;
|
||||
if (job.message && isLoading.value) polledMessage.value = job.message;
|
||||
|
||||
if (!job.active && job.status !== "running") {
|
||||
if (isJobRunning(job)) {
|
||||
sawRunning = true;
|
||||
return;
|
||||
}
|
||||
|
||||
const canFinish =
|
||||
isTerminalJob(job) && (sawRunning || jobStartedAfterSession(job));
|
||||
if (canFinish) {
|
||||
if (!finishedEmitted) {
|
||||
finishedEmitted = true;
|
||||
applyFinishedJob(job);
|
||||
@@ -180,6 +210,7 @@ function startPoll() {
|
||||
|
||||
function resetLocalState() {
|
||||
finishedEmitted = false;
|
||||
sawRunning = false;
|
||||
isLoading.value = true;
|
||||
ok.value = null;
|
||||
localTitle.value = "";
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
:message="entry.message"
|
||||
:output="entry.output"
|
||||
:log-visible="entry.logVisible"
|
||||
:session-started-at="entry.sessionStartedAt"
|
||||
@close="closeHostRemoteActionLog(entry.id)"
|
||||
@toggle-log="toggleHostRemoteActionLog(entry.id)"
|
||||
@finished="syncHostRemoteActionJobFinished(entry.id, $event)"
|
||||
|
||||
@@ -22,6 +22,8 @@ export type HostRemoteActionLogEntry = {
|
||||
title: string;
|
||||
message: string;
|
||||
output: string;
|
||||
/** ISO-время открытия окна — отсекаем stale success от прошлого job */
|
||||
sessionStartedAt: string;
|
||||
};
|
||||
|
||||
export const hostRemoteActionLogs = reactive<HostRemoteActionLogEntry[]>([]);
|
||||
@@ -207,6 +209,7 @@ export async function pollHostRemoteAction(
|
||||
title,
|
||||
message: "Выполняется на удалённом хосте…",
|
||||
output: "",
|
||||
sessionStartedAt: new Date().toISOString(),
|
||||
};
|
||||
hostRemoteActionLogs.push(entry);
|
||||
|
||||
@@ -257,6 +260,7 @@ export async function runHostRemoteAction(
|
||||
title,
|
||||
message: "Запуск на сервере SAC…",
|
||||
output: "",
|
||||
sessionStartedAt: new Date().toISOString(),
|
||||
};
|
||||
hostRemoteActionLogs.push(entry);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user