feat(NetworkMapDashboard): implement runWithOnePerKey function to ensure single task execution per node during speed tests
Publish Fast Tabler Docker image / build-and-push-fast (push) Successful in 2m0s

This commit is contained in:
2026-02-18 11:55:36 +07:00
parent 034e0d1eee
commit b5eb47e690
+42 -1
View File
@@ -25,6 +25,46 @@ async function runWithLimit(tasks, limit = 4) {
return results;
}
/**
* Выполняет задачи так, что на каждый ключ (ноду) в один момент времени
* выполняется не более одной задачи. Разные ноды — параллельно.
* getKey(i) возвращает ключ для задачи с индексом i.
*/
async function runWithOnePerKey(tasks, getKey) {
const n = tasks.length;
const keyToIndices = new Map();
for (let i = 0; i < n; i++) {
const k = String(getKey(i));
if (!keyToIndices.has(k)) keyToIndices.set(k, []);
keyToIndices.get(k).push(i);
}
const results = [];
for (let i = 0; i < n; i++) results[i] = null;
const keys = Array.from(keyToIndices.keys());
let round = 0;
while (true) {
const batch = [];
for (const k of keys) {
const indices = keyToIndices.get(k);
if (round < indices.length) batch.push(indices[round]);
}
if (batch.length === 0) break;
await Promise.all(
batch.map(async (i) => {
try {
const value = await tasks[i]();
results[i] = { value };
} catch (err) {
results[i] = { error: err };
}
})
);
round++;
}
return results;
}
export default function NetworkMapDashboard() {
const [servers, setServers] = useState([]);
const [connections, setConnections] = useState([]);
@@ -222,7 +262,8 @@ export default function NetworkMapDashboard() {
setSpeedMap((prev) => ({ ...prev, [key]: null }));
}
});
await runWithLimit(tasks, 2);
// На каждой ноде (speedTestServerId) в один момент — только один тест, чтобы не делить канал
await runWithOnePerKey(tasks, (i) => withSpeed[i].speedTestServerId);
if (speedAbortRef.current) return;
setSpeedLoading(false);
}, [connections]);