fix: node-provisioning status poll could run forever, silently or stuck on "waiting"
Follow-on from the last commit's error-handling sweep — one more spot that calls api() without a try/catch, but a different shape of problem than the others: this one's a setInterval, not a one-shot action, so a thrown/rejected promise inside it doesn't stop anything — the interval just keeps firing every 4s regardless, forever, with each failure only visible as an unhandled rejection in devtools. And even on the success path there was no upper bound at all: if the node never actually comes online (the admin closes the terminal before finishing the install command, say), "Ожидаю установки…" just sits there indefinitely with no way to know if it's still trying or has effectively given up. Now: a consecutive-error counter that gives up after 5 straight failures with a visible message pointing at the manual "Проверить" button, and an overall 150-attempt cap (10 minutes at the existing 4s interval) that stops polling and says so if the node genuinely never reports active. A single transient failure doesn't trip either — the error counter resets on any successful check, so one blip in an otherwise-working poll doesn't cut it short. Verification: extracted the poll callback's logic (can't spin up a real setInterval usefully in a one-shot Node script) and drove it by calling it directly in sequence, which is what setInterval does under the hood anyway. 6 cases: quick success, a transient error that self-heals by the next tick, 5 consecutive failures giving up with the right message at exactly attempt 5, the 150-attempt timeout firing when status never goes active, and confirming no further attempts happen at all once either give-up path triggers — not just that the message stops updating. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
parent
2b34b11391
commit
695771c79a
1 changed files with 17 additions and 1 deletions
18
admin.html
18
admin.html
|
|
@ -1802,12 +1802,28 @@ async function generateGuide() {
|
||||||
<p class="page-sub" style="margin-top:12px" id="guide-status">Ожидаю установки…</p>
|
<p class="page-sub" style="margin-top:12px" id="guide-status">Ожидаю установки…</p>
|
||||||
`;
|
`;
|
||||||
if (pollTimer) clearInterval(pollTimer);
|
if (pollTimer) clearInterval(pollTimer);
|
||||||
|
let pollAttempts = 0, pollErrors = 0;
|
||||||
pollTimer = setInterval(async () => {
|
pollTimer = setInterval(async () => {
|
||||||
const st = await api(`/admin/api/nodes/${res.code}/status`);
|
pollAttempts++;
|
||||||
|
let st;
|
||||||
|
try {
|
||||||
|
st = await api(`/admin/api/nodes/${res.code}/status`);
|
||||||
|
pollErrors = 0;
|
||||||
|
} catch (e) {
|
||||||
|
pollErrors++;
|
||||||
|
if (pollErrors >= 5) {
|
||||||
|
clearInterval(pollTimer);
|
||||||
|
document.getElementById("guide-status").innerHTML = '<span class="badge bad">Не получилось проверить статус (' + esc(e.message) + ') — проверь вручную кнопкой «Проверить» у ноды</span>';
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (st.status === "active") {
|
if (st.status === "active") {
|
||||||
clearInterval(pollTimer);
|
clearInterval(pollTimer);
|
||||||
document.getElementById("guide-status").innerHTML = '<span class="badge ok">Установлено и подключено</span>';
|
document.getElementById("guide-status").innerHTML = '<span class="badge ok">Установлено и подключено</span>';
|
||||||
loadNodes();
|
loadNodes();
|
||||||
|
} else if (pollAttempts >= 150) {
|
||||||
|
clearInterval(pollTimer);
|
||||||
|
document.getElementById("guide-status").innerHTML = '<span class="badge warn">Не дождались за 10 минут — нода появится в списке сама, когда установка на сервере закончится</span>';
|
||||||
}
|
}
|
||||||
}, 4000);
|
}, 4000);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue