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
Publish Fast Tabler Docker image / build-and-push-fast (push) Successful in 2m0s
This commit is contained in:
@@ -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]);
|
||||
|
||||
Reference in New Issue
Block a user