Commit 41c1c307 authored by nanamicat's avatar nanamicat

clean

parent be928600
...@@ -4,8 +4,8 @@ use std::collections::BTreeMap; ...@@ -4,8 +4,8 @@ use std::collections::BTreeMap;
use std::sync::Arc; use std::sync::Arc;
use tokio::sync::RwLock; use tokio::sync::RwLock;
use crate::data::{self, DATABASE, RouterID};
use crate::router::Router; use crate::router::Router;
use crate::shared::data::{self, DATABASE, RouterID};
use tower_http::cors::CorsLayer; use tower_http::cors::CorsLayer;
#[derive(Serialize, Clone)] #[derive(Serialize, Clone)]
......
use crate::data::{self, GatewayGroup, RouterID};
use std::collections::BTreeSet;
impl GatewayGroup {
pub fn search_routers(&self, routers_data: &[data::Router], groups_data: &[data::GatewayGroup]) -> BTreeSet<RouterID> {
let mut routers: BTreeSet<RouterID> = self
.children
.iter()
.flat_map(|c| groups_data.iter().find(|g| &g.name == c))
.flat_map(|g| g.search_routers(routers_data, groups_data))
.chain(routers_data.iter().filter(|r| self.location_prefix.iter().any(|p| r.location.starts_with(p))).map(|r| r.id))
.chain(self.include_routers.iter().cloned())
.collect();
for r in &self.exclude_routers {
routers.remove(r);
}
routers
}
}
use crate::api::create_app; use crate::api::create_app;
use crate::data::{DATABASE, GatewayGroupID, RouterID};
use crate::protocol::{Downlink, Uplink};
use crate::router::Router; use crate::router::Router;
use crate::settings::{CONFIG, TIMEOUT}; use crate::settings::{CONFIG, TIMEOUT};
use crate::shared::data::{DATABASE, RouterID};
use crate::shared::protocol::{Downlink, Uplink};
use anyhow::{Context, Result}; use anyhow::{Context, Result};
use net::SocketAddr; use net::SocketAddr;
use std::collections::BTreeMap; use std::collections::BTreeMap;
...@@ -13,12 +13,10 @@ use tokio::sync::RwLock; ...@@ -13,12 +13,10 @@ use tokio::sync::RwLock;
use tokio::time::Instant; use tokio::time::Instant;
mod api; mod api;
mod data;
mod gateway_group;
mod protocol;
mod quality; mod quality;
mod router; mod router;
mod settings; mod settings;
mod shared;
#[derive(Default, Debug)] #[derive(Default, Debug)]
pub struct UpdatingState { pub struct UpdatingState {
...@@ -30,16 +28,7 @@ pub struct UpdatingState { ...@@ -30,16 +28,7 @@ pub struct UpdatingState {
async fn main() -> Result<()> { async fn main() -> Result<()> {
tracing_subscriber::fmt::init(); tracing_subscriber::fmt::init();
let gateways_group: BTreeMap<GatewayGroupID, Vec<&data::Gateway>> = DATABASE let routers: BTreeMap<RouterID, Router> = DATABASE.routers.iter().map(|c| (c.id, Router::new(c.id))).collect();
.gateway_groups
.iter()
.map(|g| {
let routers = g.search_routers(&DATABASE.routers, &DATABASE.gateway_groups);
(g.id, DATABASE.gateways.iter().filter(|gw| routers.contains(&gw.router)).collect())
})
.collect();
let routers: BTreeMap<RouterID, Router> = DATABASE.routers.iter().map(|c| (c.id, Router::new(c, &gateways_group))).collect();
let routers = Arc::new(RwLock::new(routers)); let routers = Arc::new(RwLock::new(routers));
let listener = tokio::net::TcpListener::bind(CONFIG.http_bind).await?; let listener = tokio::net::TcpListener::bind(CONFIG.http_bind).await?;
...@@ -84,7 +73,7 @@ async fn main() -> Result<()> { ...@@ -84,7 +73,7 @@ async fn main() -> Result<()> {
&& let Some(router) = routers.get(&uplink.id) && let Some(router) = routers.get(&uplink.id)
&& router.is_online() && router.is_online()
&& router.last_update != now && router.last_update != now
&& let Some(downlink) = router.update(now, &routers, &gateways_group) && let Some(downlink) = router.update(now, &routers)
{ {
updating.router_id = router.id; updating.router_id = router.id;
updating.message = downlink; updating.message = downlink;
......
use crate::protocol::PeerQuality; use crate::shared::protocol::PeerQuality;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Copy, Serialize, Deserialize)] #[derive(Debug, Clone, Copy, Serialize, Deserialize)]
......
use crate::data::{DATABASE, GatewayGroupID, GatewayID, RegionID, RouterID};
use crate::protocol::{Downlink, MessageType, PeerQuality, Uplink};
use crate::quality::Quality; use crate::quality::Quality;
use crate::settings::{HALF_LIFE, PENALTY, PENALTY_MIN}; use crate::settings::{HALF_LIFE, PENALTY, PENALTY_MIN};
use crate::{UpdatingState, data}; use crate::shared::{
data::{DATABASE, GatewayGroupID, GatewayID, RegionID, RouterID},
protocol::{Downlink, MessageType, PeerQuality, Uplink},
};
use crate::{UpdatingState, shared};
use serde::Serialize; use serde::Serialize;
use std::collections::BTreeMap; use std::collections::BTreeMap;
use std::i32; use std::i32;
...@@ -34,38 +36,24 @@ impl PartialEq<Self> for Router { ...@@ -34,38 +36,24 @@ impl PartialEq<Self> for Router {
impl Eq for Router {} impl Eq for Router {}
impl Router { impl Router {
pub fn new(data: &data::Router, gateway_groups: &BTreeMap<GatewayGroupID, Vec<&data::Gateway>>) -> Self { pub fn new(id: RouterID) -> Self {
Self { Self {
id: data.id, id,
version: rand::random(), version: rand::random(),
peers: DATABASE peers: DATABASE
.connections .connections
.iter() .iter()
.filter(|(_, to)| to.contains_key(&data.id)) .filter(|(_, to)| to.contains_key(&id))
.map(|(&from, _)| (from, Default::default())) .map(|(&from, _)| (from, Default::default()))
.collect(), .collect(),
via: DATABASE.routers.iter().filter(|r| r.id != data.id).map(|r| (r.id, r.id)).collect(), via: shared::data::GatewayGroup::default_via(id),
plan: DATABASE plan: shared::data::GatewayGroup::default_plan(id),
.regions
.iter()
.enumerate()
.map(|(r, _)| {
(
RegionID(r as u8),
gateway_groups.iter().map(|(&id, g)| (id, g.iter().min_by_key(|gw| Self::guess(data, gw, r)).unwrap().id)).collect(),
)
})
.collect(),
last_seen: Instant::now(), last_seen: Instant::now(),
last_update: Instant::now(), last_update: Instant::now(),
addr: None, addr: None,
} }
} }
fn guess(data: &data::Router, gw: &data::Gateway, region: usize) -> i32 {
gw.metrics[region].saturating_add(gw.cost_outbound).saturating_add(if gw.router == data.id { 0 } else { 100 })
}
pub fn online(&mut self, addr: SocketAddr, now: Instant) { pub fn online(&mut self, addr: SocketAddr, now: Instant) {
if self.addr.is_none() { if self.addr.is_none() {
tracing::info!("router {:?} online", self.id); tracing::info!("router {:?} online", self.id);
...@@ -146,7 +134,7 @@ impl Router { ...@@ -146,7 +134,7 @@ impl Router {
} }
} }
pub fn update(&self, now: Instant, routers: &BTreeMap<RouterID, Router>, gateway_groups: &BTreeMap<GatewayGroupID, Vec<&data::Gateway>>) -> Option<Downlink> { pub fn update(&self, now: Instant, routers: &BTreeMap<RouterID, Router>) -> Option<Downlink> {
let penalty = PENALTY_MIN + (PENALTY as f32 * f32::exp2(-now.duration_since(self.last_update).div_duration_f32(HALF_LIFE))) as i32; let penalty = PENALTY_MIN + (PENALTY as f32 * f32::exp2(-now.duration_since(self.last_update).div_duration_f32(HALF_LIFE))) as i32;
let mut changed_via = BTreeMap::new(); let mut changed_via = BTreeMap::new();
let mut changed_plan = BTreeMap::new(); let mut changed_plan = BTreeMap::new();
...@@ -182,7 +170,7 @@ impl Router { ...@@ -182,7 +170,7 @@ impl Router {
// Plan updates (Gateways) // Plan updates (Gateways)
for (region_id, plan) in &self.plan { for (region_id, plan) in &self.plan {
for (&gid, gateways) in gateway_groups { for (&gid, gateways) in crate::shared::gateway_group::GATEWAYGROUPINDEX.iter() {
let current_gw = plan[&gid]; let current_gw = plan[&gid];
let current_metric = metrics[&DATABASE.gateways.iter().find(|f| f.id == current_gw).unwrap().router]; let current_metric = metrics[&DATABASE.gateways.iter().find(|f| f.id == current_gw).unwrap().router];
......
use ::config::{Config, Environment};
use serde::Deserialize; use serde::Deserialize;
use std::net::SocketAddr; use std::net::SocketAddr;
use std::time::Duration; use std::time::Duration;
...@@ -13,7 +14,4 @@ pub const HALF_LIFE: Duration = Duration::from_secs(60); ...@@ -13,7 +14,4 @@ pub const HALF_LIFE: Duration = Duration::from_secs(60);
pub const PENALTY: i32 = 100; pub const PENALTY: i32 = 100;
pub const PENALTY_MIN: i32 = 10; pub const PENALTY_MIN: i32 = 10;
use ::config::Config;
use config::Environment;
pub static CONFIG: std::sync::LazyLock<Settings> = std::sync::LazyLock::new(|| Config::builder().add_source(Environment::default()).build().unwrap().try_deserialize().unwrap()); pub static CONFIG: std::sync::LazyLock<Settings> = std::sync::LazyLock::new(|| Config::builder().add_source(Environment::default()).build().unwrap().try_deserialize().unwrap());
use crate::shared::data::{self, DATABASE, GatewayGroup, GatewayGroupID, GatewayID, RegionID, RouterID};
use std::collections::{BTreeMap, BTreeSet};
use std::sync::LazyLock;
pub static GATEWAYGROUPINDEX: LazyLock<BTreeMap<GatewayGroupID, Vec<&'static data::Gateway>>> = LazyLock::new(|| {
DATABASE
.gateway_groups
.iter()
.map(|g| {
let routers = g.search_routers(&DATABASE.routers, &DATABASE.gateway_groups);
(g.id, DATABASE.gateways.iter().filter(|gw| routers.contains(&gw.router)).collect())
})
.collect()
});
impl GatewayGroup {
fn search_routers(&self, routers_data: &[data::Router], groups_data: &[Self]) -> BTreeSet<RouterID> {
let mut routers: BTreeSet<RouterID> = self
.children
.iter()
.flat_map(|c| groups_data.iter().find(|g| &g.name == c))
.flat_map(|g| g.search_routers(routers_data, groups_data))
.chain(routers_data.iter().filter(|r| self.location_prefix.iter().any(|p| r.location.starts_with(p))).map(|r| r.id))
.chain(self.include_routers.iter().cloned())
.collect();
for r in &self.exclude_routers {
routers.remove(r);
}
routers
}
pub fn default_via(id: RouterID) -> BTreeMap<RouterID, RouterID> {
DATABASE.routers.iter().filter(|r| r.id != id).map(|r| (r.id, r.id)).collect()
}
pub fn default_plan(id: RouterID) -> BTreeMap<RegionID, BTreeMap<GatewayGroupID, GatewayID>> {
DATABASE
.regions
.iter()
.enumerate()
.map(|(r, _)| {
(
RegionID(r as u8),
GATEWAYGROUPINDEX.iter().map(|(&gid, g)| (gid, g.iter().min_by_key(|gw| Self::guess(id, gw, r)).unwrap().id)).collect(),
)
})
.collect()
}
fn guess(id: RouterID, gw: &data::Gateway, region: usize) -> i32 {
gw.metrics[region].saturating_add(gw.cost_outbound).saturating_add(if gw.router == id { 0 } else { 100 })
}
}
pub mod data;
pub mod gateway_group;
pub mod protocol;
#![allow(dead_code)]
use bincode::{Decode, Encode}; use bincode::{Decode, Encode};
use serde::Serialize; use serde::Serialize;
use std::collections::BTreeMap; use std::collections::BTreeMap;
use crate::data::{GatewayGroupID, GatewayID, RegionID, RouterID}; use crate::shared::data::{GatewayGroupID, GatewayID, RegionID, RouterID};
#[derive(Encode, Decode)]
pub struct Hello {
pub time: u32,
}
#[derive(Encode, Decode, Default, Debug, Eq, PartialEq, Copy, Clone)] #[derive(Encode, Decode, Default, Debug, Eq, PartialEq, Copy, Clone)]
pub enum MessageType { pub enum MessageType {
......
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