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 {
export interface Change {
seq: number,
via: Record<number, number>,
// plan: Record<number, number>
plan: Record<number, number>
}
// 路由器向路由器发送的消息
......
......@@ -6,28 +6,30 @@ import assert from 'assert';
import { Quality } from './Quality';
import _ from 'lodash';
import config from '../config/config.json';
import gatewayGroups from '../import/data/GatewayGroup.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 {
static all: Router[] = routers.map(s => new Router(s.id));
static all: Router[] = routers.map((s) => new Router(s.id));
static updating?: {
router: Router,
message: Change
router: Router;
message: Change;
};
static groups: Record<number, Router[]>;
seq = 0;
peers: Record<number, PeerQuality> = {};
via: Map<Router, Router> = new Map();
// plan: Record<number, number> = {};
plan: Record<number, number> = {};
time: number = 0;
rinfo?: RemoteInfo;
constructor(public id: number) {
}
constructor(public id: number) {}
static update(socket: Socket) {
for (const from of Router.all) from.update(socket);
......@@ -36,7 +38,7 @@ export class Router {
reset() {
this.seq = 0;
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);
}
if (Router.updating?.router == this) Router.updating = undefined;
......@@ -54,13 +56,15 @@ export class Router {
Router.updating = undefined;
Router.update(socket);
}
} else if (data.ack === 0) { // 客户端重启
} else if (data.ack === 0) {
// 客户端重启
this.reset();
this.time = Date.now();
this.send(socket, { seq: this.seq, via: {} });
} else if (this.seq == 0) { // 服务器重启或客户端下线
this.send(socket, { seq: this.seq, via: {}, plan: {} });
} else if (this.seq == 0) {
// 服务器重启或客户端下线
this.time = Date.now();
this.send(socket, { seq: this.seq, via: {} });
this.send(socket, { seq: this.seq, via: {}, plan: {} });
} else {
console.log(`ignoring packet from ${data.id}, packet ack=${data.ack}, server seq=${this.seq}`);
}
......@@ -82,12 +86,12 @@ export class Router {
const changedVia: 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 [bestRoute, bestMetric] = _.minBy(items, (([v, m]) => m))!;
const [bestRoute, bestMetric] = _.minBy(items, ([v, m]) => m)!;
// 变更
if (currentRoute !== bestRoute && bestMetric + config.throttle < currentMetric) {
......@@ -100,27 +104,27 @@ export class Router {
}
}
// 计算 route plan
// 凡是自己可以作为那个 plan 出口的,是不会计算直接跳过的,所以这里有 plan 到自己的意思是,没有找到任何一个通的可以出的地方,所以只好从自己出了
const changedPlan: Record<number, number> = {};
// for (const plan of plans.filter(plan => !plan.routers.includes(this.id))) {
// const currentPlan = this.plan[plan.id];
// const currentMetric = currentPlan === this.id ? Infinity : metric[currentPlan];
// const items = plan.routers.map(to => [to, metric[to]]);
// const [bestPlan, bestMetric] = _.minBy(items, ([t, m]) => m)!;
//
// 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[plan.id] = changedPlan[plan.id] = bestPlan;
// }
// }
for (const [_groupId, groupRouters] of Object.entries(Router.groups).filter(([_, g]) => !g.includes(this))) {
const groupId = parseInt(_groupId);
const currentPlan = this.plan[groupId];
const currentMetric = currentPlan === this.id ? Infinity : metric[currentPlan];
const items = groupRouters.map((to) => [to.id, metric[to.id]]);
const [bestPlan, bestMetric] = _.minBy(items, ([_, m]) => m)!;
if (currentPlan !== this.id && bestMetric === Infinity) {
// 原来通的,现在不通了
this.plan[groupId] = changedPlan[groupId] = this.id;
} else if (currentPlan !== bestPlan && bestMetric + config.throttle < currentMetric) {
this.plan[groupId] = changedPlan[groupId] = bestPlan;
}
}
if (!_.isEmpty(changedVia) || !_.isEmpty(changedPlan)) {
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 };
this.send(socket, message);
}
......@@ -163,3 +167,17 @@ export class Router {
}
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