diff --git a/backend/services/networkMapScheduler.js b/backend/services/networkMapScheduler.js index 71cf2e9..e588d82 100644 --- a/backend/services/networkMapScheduler.js +++ b/backend/services/networkMapScheduler.js @@ -295,7 +295,12 @@ async function runJob(opts) { return null; } }); - await runWithOnePerKey(speedTasks, (i) => withSpeed[i].speedTestServerId); + // В один момент — только один тест на один сервер назначения (удалённый конец туннеля), + // иначе несколько замеров к одному хостингу делят канал и дают заниженные результаты + await runWithOnePerKey(speedTasks, (i) => { + const c = withSpeed[i]; + return c.speedTestServerId === c.fromKey ? c.toKey : c.fromKey; + }); } await writeCache(pingMap, speedMap); diff --git a/frontend/src/NetworkMapDashboard.jsx b/frontend/src/NetworkMapDashboard.jsx index 7c243a9..aac5b11 100644 --- a/frontend/src/NetworkMapDashboard.jsx +++ b/frontend/src/NetworkMapDashboard.jsx @@ -321,8 +321,12 @@ export default function NetworkMapDashboard() { } } }); - // На каждой ноде (speedTestServerId) в один момент — только один тест, чтобы не делить канал - await runWithOnePerKey(tasks, (i) => withSpeed[i].speedTestServerId); + // В один момент — только один тест на один сервер назначения (удалённый конец туннеля), + // иначе несколько замеров к одному хостингу делят канал и дают заниженные результаты + await runWithOnePerKey(tasks, (i) => { + const c = withSpeed[i]; + return c.speedTestServerId === c.fromKey ? c.toKey : c.fromKey; + }); if (speedAbortRef.current) return; setSpeedLoading(false); }, [connections]);