You need to sign in or sign up before continuing.
Commit 48e2efa5 authored by 神楽坂玲奈's avatar 神楽坂玲奈

plan

parent 8ec21ed7
Pipeline #16305 passed with stages
in 3 minutes and 9 seconds
...@@ -17,7 +17,7 @@ export interface Report { ...@@ -17,7 +17,7 @@ export interface Report {
export interface Change { export interface Change {
seq: number, seq: number,
via: Record<number, number>, via: Record<number, number>,
// plan: Record<number, number> plan: Record<number, number>
} }
// 路由器向路由器发送的消息 // 路由器向路由器发送的消息
......
...@@ -6,28 +6,30 @@ import assert from 'assert'; ...@@ -6,28 +6,30 @@ import assert from 'assert';
import { Quality } from './Quality'; import { Quality } from './Quality';
import _ from 'lodash'; import _ from 'lodash';
import config from '../config/config.json'; import config from '../config/config.json';
import gatewayGroups from '../import/data/GatewayGroup.json';
import _connections from '../import/connections.json'; import _connections from '../import/connections.json';
import { GatewayGroup } from '../import/scripts/GatewayGroup';
const connections: Record<number, Record<number, { metric: number, protocol: string }>> = _connections; const connections: Record<number, Record<number, { metric: number; protocol: string }>> = _connections;
export class Router { export class Router {
static all: Router[] = routers.map(s => new Router(s.id)); static all: Router[] = routers.map((s) => new Router(s.id));
static updating?: { static updating?: {
router: Router, router: Router;
message: Change message: Change;
}; };
static groups: Record<number, Router[]>;
seq = 0; seq = 0;
peers: Record<number, PeerQuality> = {}; peers: Record<number, PeerQuality> = {};
via: Map<Router, Router> = new Map(); via: Map<Router, Router> = new Map();
// plan: Record<number, number> = {}; plan: Record<number, number> = {};
time: number = 0; time: number = 0;
rinfo?: RemoteInfo; rinfo?: RemoteInfo;
constructor(public id: number) { constructor(public id: number) {}
}
static update(socket: Socket) { static update(socket: Socket) {
for (const from of Router.all) from.update(socket); for (const from of Router.all) from.update(socket);
...@@ -36,7 +38,7 @@ export class Router { ...@@ -36,7 +38,7 @@ export class Router {
reset() { reset() {
this.seq = 0; this.seq = 0;
this.peers = {}; this.peers = {};
for (const router of Router.all.filter(r => r.id !== this.id)) { for (const router of Router.all.filter((r) => r.id !== this.id)) {
this.via.set(router, router); this.via.set(router, router);
} }
if (Router.updating?.router == this) Router.updating = undefined; if (Router.updating?.router == this) Router.updating = undefined;
...@@ -54,13 +56,15 @@ export class Router { ...@@ -54,13 +56,15 @@ export class Router {
Router.updating = undefined; Router.updating = undefined;
Router.update(socket); Router.update(socket);
} }
} else if (data.ack === 0) { // 客户端重启 } else if (data.ack === 0) {
// 客户端重启
this.reset(); this.reset();
this.time = Date.now(); this.time = Date.now();
this.send(socket, { seq: this.seq, via: {} }); this.send(socket, { seq: this.seq, via: {}, plan: {} });
} else if (this.seq == 0) { // 服务器重启或客户端下线 } else if (this.seq == 0) {
// 服务器重启或客户端下线
this.time = Date.now(); this.time = Date.now();
this.send(socket, { seq: this.seq, via: {} }); this.send(socket, { seq: this.seq, via: {}, plan: {} });
} else { } else {
console.log(`ignoring packet from ${data.id}, packet ack=${data.ack}, server seq=${this.seq}`); console.log(`ignoring packet from ${data.id}, packet ack=${data.ack}, server seq=${this.seq}`);
} }
...@@ -82,12 +86,12 @@ export class Router { ...@@ -82,12 +86,12 @@ export class Router {
const changedVia: Record<number, number> = {}; const changedVia: Record<number, number> = {};
const metric: Record<number, number> = {}; const metric: Record<number, number> = {};
for (const to of Router.all.filter(r => r.id !== this.id)) { for (const to of Router.all.filter((r) => r.id !== this.id)) {
// 计算最优下一跳 // 计算最优下一跳
const items: [Router, number][] = Router.all.filter(r => r.id !== this.id).map(r => [r, this.route_quality(to, r).metric()]); const items: [Router, number][] = Router.all.filter((r) => r.id !== this.id).map((r) => [r, this.route_quality(to, r).metric()]);
const [currentRoute, currentMetric] = items.find(([v, m]) => v === this.via.get(to))!; const [currentRoute, currentMetric] = items.find(([v, m]) => v === this.via.get(to))!;
const [bestRoute, bestMetric] = _.minBy(items, (([v, m]) => m))!; const [bestRoute, bestMetric] = _.minBy(items, ([v, m]) => m)!;
// 变更 // 变更
if (currentRoute !== bestRoute && bestMetric + config.throttle < currentMetric) { if (currentRoute !== bestRoute && bestMetric + config.throttle < currentMetric) {
...@@ -100,27 +104,27 @@ export class Router { ...@@ -100,27 +104,27 @@ export class Router {
} }
} }
// 计算 route plan // 计算 route plan
// 凡是自己可以作为那个 plan 出口的,是不会计算直接跳过的,所以这里有 plan 到自己的意思是,没有找到任何一个通的可以出的地方,所以只好从自己出了 // 凡是自己可以作为那个 plan 出口的,是不会计算直接跳过的,所以这里有 plan 到自己的意思是,没有找到任何一个通的可以出的地方,所以只好从自己出了
const changedPlan: Record<number, number> = {}; const changedPlan: Record<number, number> = {};
// for (const plan of plans.filter(plan => !plan.routers.includes(this.id))) { for (const [_groupId, groupRouters] of Object.entries(Router.groups).filter(([_, g]) => !g.includes(this))) {
// const currentPlan = this.plan[plan.id]; const groupId = parseInt(_groupId);
// const currentMetric = currentPlan === this.id ? Infinity : metric[currentPlan]; const currentPlan = this.plan[groupId];
// const items = plan.routers.map(to => [to, metric[to]]); const currentMetric = currentPlan === this.id ? Infinity : metric[currentPlan];
// const [bestPlan, bestMetric] = _.minBy(items, ([t, m]) => m)!; const items = groupRouters.map((to) => [to.id, metric[to.id]]);
// const [bestPlan, bestMetric] = _.minBy(items, ([_, m]) => m)!;
// if (currentPlan !== this.id && bestMetric === Infinity) {
// // 原来通的,现在不通了 if (currentPlan !== this.id && bestMetric === Infinity) {
// this.plan[plan.id] = changedPlan[plan.id] = this.id; // 原来通的,现在不通了
// } else if (currentPlan !== bestPlan && bestMetric + config.throttle < currentMetric) { this.plan[groupId] = changedPlan[groupId] = this.id;
// this.plan[plan.id] = changedPlan[plan.id] = bestPlan; } else if (currentPlan !== bestPlan && bestMetric + config.throttle < currentMetric) {
// } this.plan[groupId] = changedPlan[groupId] = bestPlan;
// } }
}
if (!_.isEmpty(changedVia) || !_.isEmpty(changedPlan)) { if (!_.isEmpty(changedVia) || !_.isEmpty(changedPlan)) {
this.seq++; this.seq++;
const message: Change = { seq: this.seq, via: changedVia }; const message: Change = { seq: this.seq, via: changedVia, plan: changedPlan };
Router.updating = { router: this, message }; Router.updating = { router: this, message };
this.send(socket, message); this.send(socket, message);
} }
...@@ -163,3 +167,17 @@ export class Router { ...@@ -163,3 +167,17 @@ export class Router {
} }
for (const router of Router.all) router.reset(); for (const router of Router.all) router.reset();
function groupRouters(g: GatewayGroup): Router[] {
return _.uniq(
g.locationPrefix
.flatMap((p) => routers.filter((r) => r.location.startsWith(p)))
.concat(routers.filter((r) => g.includeRouters.includes(r.name)))
.filter((r) => !g.excludeRouters.includes(r.name))
.map((r) => Router.all.find((r1) => r1.id === r.id)!)
.concat(gatewayGroups.filter((g1) => g.children.includes(g1.name)).flatMap((c) => groupRouters(c)))
);
}
Router.groups = Object.fromEntries(gatewayGroups.map((g) => [g.id, groupRouters(g)]));
console.log(Router.groups);
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment