Commit d6abf586 authored by nanamicat's avatar nanamicat

metric

parent 377c3acf
Pipeline #42459 passed with stages
in 1 minute and 8 seconds
......@@ -75,7 +75,7 @@ async fn main() -> Result<()> {
let now = Instant::now();
// 将超时的路由器下线
for router in routers.values_mut() {
if router.is_online() && router.time.duration_since(now) >= TIMEOUT {
if router.is_online() && router.last_seen.duration_since(now) >= TIMEOUT {
router.offline();
}
}
......@@ -92,7 +92,8 @@ async fn main() -> Result<()> {
} else if updating.router_id == 0
&& now.duration_since(start) >= TIMEOUT // 刚启动时静默,先学习
&& let Some(router) = routers.get(&uplink.id)
&& let Some(downlink) = router.update(&routers, &connections)
&& router.is_online()
&& let Some(downlink) = router.update(now, &routers, &connections)
{
updating.router_id = router.id;
updating.message = downlink;
......
......@@ -23,7 +23,7 @@ impl Quality {
if self.reliability == 0.0 {
i32::MAX
} else {
self.delay + ((1.0 - self.reliability) * 2000.0).round() as i32 + self.cost as i32
self.delay + ((1.0 - self.reliability) * 3000.0).round() as i32 + self.cost as i32
}
}
}
......
use crate::UpdatingState;
use crate::data::{ConnectionData, RouterData};
use crate::protocol::{Downlink, MessageType, PeerQuality, Uplink};
use crate::quality::Quality;
use crate::settings::THROTTLE;
use crate::settings::{HALF_LIFE, PENALTY};
use crate::UpdatingState;
use serde::Serialize;
use std::collections::BTreeMap;
use std::net::SocketAddr;
......@@ -18,7 +18,9 @@ pub struct Router {
pub via: BTreeMap<u8, u8>, // dst router_id -> next hop router_id
pub plan: BTreeMap<u8, BTreeMap<u8, u8>>, // group id -> region id -> gateway_id
#[serde(skip)]
pub time: Instant, // ms
pub last_seen: Instant,
#[serde(skip)]
pub last_update: Instant,
#[serde(skip)]
pub addr: Option<SocketAddr>,
// Static config
......@@ -45,7 +47,8 @@ impl Router {
.collect(),
via: routers.iter().filter(|r| r.id != data.id).map(|r| (r.id, r.id)).collect(),
plan: BTreeMap::new(),
time: Instant::now(),
last_seen: Instant::now(),
last_update: Instant::now(),
addr: None,
}
// router.reset(all_router_ids);
......@@ -63,7 +66,7 @@ impl Router {
tracing::info!("router {} online", self.id);
}
self.addr = Some(addr);
self.time = now;
self.last_seen = now;
}
pub fn offline(&mut self) {
......@@ -136,7 +139,12 @@ impl Router {
}
}
pub fn update(&self, routers: &BTreeMap<u8, Router>, connections: &BTreeMap<u8, BTreeMap<u8, ConnectionData>>) -> Option<Downlink> {
pub fn penalty(&self, now: Instant) -> i32 {
(PENALTY as f32 * f32::exp2(-now.duration_since(self.last_update).div_duration_f32(HALF_LIFE))) as i32
}
pub fn update(&self, now: Instant, routers: &BTreeMap<u8, Router>, connections: &BTreeMap<u8, BTreeMap<u8, ConnectionData>>) -> Option<Downlink> {
let penalty = self.penalty(now);
let mut changed_via: BTreeMap<u8, u8> = BTreeMap::new();
// let mut metric: BTreeMap<u8, i32> = BTreeMap::new();
......@@ -155,7 +163,7 @@ impl Router {
// 无论如何都不可达就标记为直连
changed_via.insert(to.id, to.id);
}
Some((best_router, best_metric)) if current_router != *best_router && (*best_metric + THROTTLE < current_metric) => {
Some((best_router, best_metric)) if current_router != *best_router && (*best_metric + penalty < current_metric) => {
changed_via.insert(to.id, best_router.id);
}
_ => {}
......
......@@ -8,5 +8,6 @@ pub struct Settings {
pub http_bind: SocketAddr,
}
pub const TIMEOUT: Duration = Duration::from_secs(10);
pub const THROTTLE: i32 = 20;
pub const TIMEOUT: Duration = Duration::from_secs(20);
pub const HALF_LIFE: Duration = Duration::from_secs(60);
pub const PENALTY: i32 = 100;
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