fix(ui): single-flight scan poll so status line does not alternate
Made-with: Cursor
This commit is contained in:
@@ -249,6 +249,8 @@
|
|||||||
/** @type {{if_index:number,bridge_port:number,mac:string,learned_ip:string}[]} */
|
/** @type {{if_index:number,bridge_port:number,mac:string,learned_ip:string}[]} */
|
||||||
let lastPortDevItems = [];
|
let lastPortDevItems = [];
|
||||||
let selectedFdbKey = null;
|
let selectedFdbKey = null;
|
||||||
|
/** Увеличивается при каждом новом pollScanUntilDone — снимает гонку createScan vs watchScan (чередование строк статуса). */
|
||||||
|
let scanPollSeq = 0;
|
||||||
|
|
||||||
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
|
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
|
||||||
|
|
||||||
@@ -287,31 +289,47 @@
|
|||||||
* @param {{ intervalMs?: number, maxWaitMs?: number, onDone?: function }} opts
|
* @param {{ intervalMs?: number, maxWaitMs?: number, onDone?: function }} opts
|
||||||
*/
|
*/
|
||||||
async function pollScanUntilDone(scanId, opts = {}) {
|
async function pollScanUntilDone(scanId, opts = {}) {
|
||||||
|
const mySeq = ++scanPollSeq;
|
||||||
const intervalMs = opts.intervalMs ?? 1000;
|
const intervalMs = opts.intervalMs ?? 1000;
|
||||||
const maxWaitMs = opts.maxWaitMs ?? 20 * 60 * 1000;
|
const maxWaitMs = opts.maxWaitMs ?? 20 * 60 * 1000;
|
||||||
const started = Date.now();
|
const started = Date.now();
|
||||||
while (Date.now() - started < maxWaitMs) {
|
while (Date.now() - started < maxWaitMs) {
|
||||||
|
if (mySeq !== scanPollSeq) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
let job;
|
let job;
|
||||||
try {
|
try {
|
||||||
job = await fetchScanJob(scanId);
|
job = await fetchScanJob(scanId);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
setStatus(`Ошибка опроса скана: ${e.message}`);
|
if (mySeq === scanPollSeq) {
|
||||||
|
setStatus(`Ошибка опроса скана: ${e.message}`);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (mySeq !== scanPollSeq) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
setStatus(describeScanProgress(job));
|
setStatus(describeScanProgress(job));
|
||||||
if (job.status === "done" || job.status === "failed" || job.status === "canceled") {
|
if (job.status === "done" || job.status === "failed" || job.status === "canceled") {
|
||||||
|
if (mySeq !== scanPollSeq) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
if (opts.onDone) {
|
if (opts.onDone) {
|
||||||
try {
|
try {
|
||||||
await opts.onDone(job);
|
await opts.onDone(job);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
setStatus((statusEl.textContent || "") + ` | Ошибка в onDone: ${e.message}`);
|
if (mySeq === scanPollSeq) {
|
||||||
|
setStatus((statusEl.textContent || "") + ` | Ошибка в onDone: ${e.message}`);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return job;
|
return job;
|
||||||
}
|
}
|
||||||
await sleep(intervalMs);
|
await sleep(intervalMs);
|
||||||
}
|
}
|
||||||
setStatus(`Таймаут ожидания скана ${scanId} (${Math.round(maxWaitMs / 60000)} мин).`);
|
if (mySeq === scanPollSeq) {
|
||||||
|
setStatus(`Таймаут ожидания скана ${scanId} (${Math.round(maxWaitMs / 60000)} мин).`);
|
||||||
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user