fix(optimizer): убрать лишние поиски и расчёты маршрутов

This commit is contained in:
Denozordec committed 2026-10-07 13:16:12 +07:00
1 parent 057f0d352a
commit 4fee9e371f
8 files changed
+164 -9

No files matched your search

+13 -3
View File
@@ -512,8 +512,17 @@ export function buildLiveOptimizerData(
}
}
const wanJhById = new Map<string, Map<string, WanJhLeg>>()
for (const leg of wanJhLegs) {
let byHost = wanJhById.get(leg.wanId)
if (!byHost) { byHost = new Map(); wanJhById.set(leg.wanId, byHost) }
// Keep the first match, as the former Array.find did.
if (!byHost.has(leg.jhId)) byHost.set(leg.jhId, leg)
}
const jhExMap = new Map<string, JhExLeg>()
for (const jh of jumpHosts) {
// Without a configured WAN, no full route can consume a JH→Exit leg.
for (const jh of home.wans.length ? jumpHosts : []) {
for (const ex of exitNodes) {
const jhRow = byId.get(jh.id)
const exRow = byId.get(ex.id)
@@ -544,10 +553,11 @@ export function buildLiveOptimizerData(
const fullRoutes: FullRoute[] = []
for (const wan of home.wans) {
for (const jh of jumpHosts) {
const hw = wanJhById.get(wan.id)?.get(jh.id)
if (!hw) continue
for (const ex of exitNodes) {
const hw = wanJhLegs.find((l) => l.wanId === wan.id && l.jhId === jh.id)
const je = jhExMap.get(`${jh.id}::${ex.id}`)
if (!hw || !je) continue
if (!je) continue
const totalPing = hw.pingMs + je.pingMs
const dl = Math.min(hw.dlMbps, je.dlMbps)
const ul = Math.min(hw.ulMbps, je.ulMbps)
+33
View File
@@ -0,0 +1,33 @@
import {test} from "node:test"
import assert from "node:assert/strict"
import {buildLiveOptimizerData,DEFAULT_ROUTE_AI_OPTIMIZER_SETTINGS,type OptimizerApiServer,type RouteOptimizerSpeedProbe} from "./route-optimizer-data"
const common={host:"192.0.2.1",enabled:true,status:"online" as const,latency:10,country:"RU",site:"TEST",model:"CHR"}
const wans=Array.from({length:2},(_,i)=>({id:`w${i+1}`,name:`WAN${i+1}`,iface:`ether${i+1}`,isp:"ISP",ip:"198.51.100.1",maxDl:100,maxUl:100}))
const rows:OptimizerApiServer[]=[{...common,id:1,name:"Home",type:"home-router",wanUplinks:wans},...Array.from({length:2},(_,i)=>({...common,id:i+2,name:`Jump${i}`,type:"jump-host" as const})),...Array.from({length:2},(_,i)=>({...common,id:i+4,name:`Exit${i}`,type:"exit-node" as const}))]
const probe=(id:string,src:number,dst:number,iface:string):RouteOptimizerSpeedProbe=>({id,srcServerId:String(src),dstServerId:String(dst),srcInterface:iface,dstInterface:"",enabled:true,lastPingRttMs:10,lastPingLossPct:0,lastTxAvgMbps:100,lastRxAvgMbps:100,lastPingAt:"2026-10-07T00:00:00Z"})
test("full route keeps the matching WAN/JH and JH/Exit probe snapshots",()=>{
const probes=[...wans.flatMap(wan=>[2,3].map(jh=>probe(`wan-${wan.id}-${jh}`,1,jh,wan.iface))),...[2,3].flatMap(jh=>[4,5].map(exit=>probe(`exit-${jh}-${exit}`,jh,exit,"")))]
const entry=buildLiveOptimizerData(rows,[],DEFAULT_ROUTE_AI_OPTIMIZER_SETTINGS,probes).homes[0]
assert.equal(entry.fullRoutes.length,8);assert.equal(new Set(entry.fullRoutes.map(route=>route.id)).size,8)
for(const route of entry.fullRoutes){
assert.equal(route.hw.observed?.probeId,`wan-${route.wan.id}-${route.jh.id}`)
assert.equal(route.je.observed?.probeId,`exit-${route.jh.id}-${route.exit.id}`)
assert.equal(route.hw.wanId,route.wan.id);assert.equal(route.hw.jhId,route.jh.id)
assert.equal(route.je.jhId,route.jh.id);assert.equal(route.je.exitId,route.exit.id)
}
assert.equal(entry.bestRoute,entry.fullRoutes[0])
})
test("equal modeled routes keep original WAN/JH/Exit order and unknown observations",()=>{
const entry=buildLiveOptimizerData(rows,[],DEFAULT_ROUTE_AI_OPTIMIZER_SETTINGS).homes[0]
assert.deepEqual(entry.fullRoutes.map(route=>route.id),wans.flatMap(wan=>[2,3].flatMap(jh=>[4,5].map(exit=>`1-${wan.id}-${jh}-${exit}`))))
assert.ok(entry.fullRoutes.every(route=>route.hw.observed?.probeId===null&&route.je.observed?.probeId===null))
})
test("no WAN leaves routes and community indices unknown without generating JH/Exit legs",()=>{
const inventory=rows.map(row=>row.id===1?{...row,wanUplinks:[]}:row)
const entry=buildLiveOptimizerData(inventory,[{serverId:"1",rules:[{id:"a",community:"65001:1",gateway:"192.0.2.1",gatewayTunnelId:"",description:""}]}],DEFAULT_ROUTE_AI_OPTIMIZER_SETTINGS).homes[0]
assert.deepEqual(entry.wanJhLegs,[]);assert.deepEqual(entry.fullRoutes,[]);assert.equal(entry.bestRoute,null)
assert.equal(entry.commRecs.length,1);assert.equal(entry.commRecs[0].current,null);assert.equal(entry.commRecs[0].recommended,null)
})