feat: ingest burst hardening — defer lifecycle/auth, workers, nginx (v0.5.5)

Defer notify_lifecycle and notify_auth_login after commit; SAC_UVICORN_WORKERS via sac-api-start.sh; nginx /api/v1/events timeout; mass-update confirm in Hosts UI.
This commit is contained in:
2026-07-08 13:16:13 +10:00
parent 1ad01534f1
commit b148b558c3
14 changed files with 189 additions and 12 deletions
+35
View File
@@ -138,6 +138,7 @@ import {
remoteActionTitleForHost,
} from "../utils/hostAgentUpgrade";
import {
hostRemoteActionLogs,
isHostRemoteActionActive,
pollHostRemoteAction,
runHostRemoteAction,
@@ -244,6 +245,37 @@ function isVersionOutdated(h: HostSummary): boolean {
return isAgentVersionOutdated(h.product_version, reference);
}
function countOutdatedUpgradeableHosts(): number {
return (data.value?.items ?? []).filter(
(h) => isGitAgentUpgradeAvailable(h, data.value) && isVersionOutdated(h),
).length;
}
function countActiveRemoteUpgrades(): number {
return hostRemoteActionLogs.filter((e) => e.loading).length;
}
function confirmMassUpgradeIfNeeded(hostname: string): boolean {
const active = countActiveRemoteUpgrades();
const outdated = countOutdatedUpgradeableHosts();
if (active >= 2) {
return window.confirm(
`Сейчас обновляется ${active} хост(ов). Рекомендуется пачками по 2–3. Продолжить обновление «${hostname}»?`,
);
}
if (outdated > 3 && active >= 1) {
return window.confirm(
`Устарело агентов на странице: ${outdated}, уже идёт обновление. Продолжить «${hostname}»?`,
);
}
if (outdated > 3) {
return window.confirm(
`Устарело агентов на странице: ${outdated}. Рекомендуется обновлять пачками по 2–3, не все сразу. Продолжить «${hostname}»?`,
);
}
return true;
}
async function startAgentUpgrade(h: HostSummary) {
if (!isGitAgentUpgradeAvailable(h, data.value)) {
return;
@@ -252,6 +284,9 @@ async function startAgentUpgrade(h: HostSummary) {
showHostRemoteActionLog(h.id);
return;
}
if (!confirmMassUpgradeIfNeeded(h.hostname)) {
return;
}
const kind = remoteActionKindForHost(h);
if (!kind) return;
void runHostRemoteAction(h.id, remoteActionTitleForHost(h), kind);