Files
multiverse/xcom-ultra/xcu-orbital-router/src/lib.rs
T

127 lines
5.9 KiB
Rust

#![deny(warnings)]
#![allow(dead_code)]
//! [TSM.ID].[11031972] -- Platform X Ecosystem
//! xcu-orbital-router -- Mesh Routing with Latency Scoring & Circuit Breaker
use std::collections::HashMap;
#[derive(Debug)]
pub enum OrbitalError { NoRoute(String), CircuitOpen(String), AllPathsFailed(String) }
impl std::fmt::Display for OrbitalError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self { Self::NoRoute(e) => write!(f, "No route: {e}"), Self::CircuitOpen(e) => write!(f, "Circuit: {e}"), Self::AllPathsFailed(e) => write!(f, "All failed: {e}") }
}
}
impl std::error::Error for OrbitalError {}
#[derive(Debug, Clone)]
pub struct MeshNode { pub id: String, pub region: String, pub latency_ms: u32, pub capacity: u32, pub current_load: u32 }
#[derive(Debug, Clone)]
pub struct MeshEdge { pub from: String, pub to: String, pub latency_ms: u32, pub bandwidth_mbps: u32 }
#[derive(Debug, Clone)]
pub struct CircuitBreaker { pub failures: u32, pub threshold: u32, pub is_open: bool, pub last_failure: u64 }
impl CircuitBreaker {
pub fn new(threshold: u32) -> Self { Self { failures: 0, threshold, is_open: false, last_failure: 0 } }
pub fn record_failure(&mut self, now: u64) { self.failures += 1; self.last_failure = now; if self.failures >= self.threshold { self.is_open = true; } }
pub fn record_success(&mut self) { self.failures = 0; self.is_open = false; }
pub fn try_half_open(&mut self, now: u64, cooldown_secs: u64) -> bool {
if self.is_open && now - self.last_failure > cooldown_secs { self.is_open = false; self.failures = self.threshold - 1; return true; }
!self.is_open
}
}
pub struct OrbitalRouter {
nodes: HashMap<String, MeshNode>,
edges: Vec<MeshEdge>,
breakers: HashMap<String, CircuitBreaker>,
breaker_threshold: u32,
}
impl OrbitalRouter {
pub fn new(breaker_threshold: u32) -> Self {
Self { nodes: HashMap::new(), edges: Vec::new(), breakers: HashMap::new(), breaker_threshold }
}
pub fn add_node(&mut self, node: MeshNode) { self.nodes.insert(node.id.clone(), node); }
pub fn add_edge(&mut self, edge: MeshEdge) { self.edges.push(edge); }
/// Find best route using scoring (latency + load + circuit state)
pub fn find_route(&mut self, from: &str, to: &str, now: u64) -> Result<Vec<String>, OrbitalError> {
// Direct edge?
let direct: Vec<&MeshEdge> = self.edges.iter().filter(|e| e.from == from && e.to == to).collect();
for edge in &direct {
let key = format!("{}->{}", edge.from, edge.to);
let breaker = self.breakers.entry(key).or_insert_with(|| CircuitBreaker::new(self.breaker_threshold));
if breaker.try_half_open(now, 30) {
return Ok(vec![from.into(), to.into()]);
}
}
// Multi-hop: find via intermediate nodes
let intermediates: Vec<String> = self.edges.iter()
.filter(|e| e.from == from)
.flat_map(|e1| {
self.edges.iter()
.filter(|e2| e2.from == e1.to && e2.to == to)
.map(move |e2| (e1.clone(), e2.clone()))
})
.map(|(e1, _)| e1.to.clone())
.collect();
if intermediates.is_empty() { return Err(OrbitalError::NoRoute(format!("{from} -> {to}"))); }
// Score intermediates by latency + load
let mut best_hop = intermediates[0].clone();
let mut best_score = f64::MAX;
for hop in &intermediates {
let key = format!("{from}->{hop}");
let breaker = self.breakers.entry(key).or_insert_with(|| CircuitBreaker::new(self.breaker_threshold));
if !breaker.try_half_open(now, 30) { continue; }
if let Some(node) = self.nodes.get(hop) {
let load_ratio = if node.capacity > 0 { node.current_load as f64 / node.capacity as f64 } else { 1.0 };
let score = node.latency_ms as f64 + load_ratio * 100.0;
if score < best_score { best_score = score; best_hop = hop.clone(); }
}
}
Ok(vec![from.into(), best_hop, to.into()])
}
pub fn report_failure(&mut self, from: &str, to: &str, now: u64) {
let key = format!("{from}->{to}");
let breaker = self.breakers.entry(key).or_insert_with(|| CircuitBreaker::new(self.breaker_threshold));
breaker.record_failure(now);
}
pub fn report_success(&mut self, from: &str, to: &str) {
let key = format!("{from}->{to}");
if let Some(breaker) = self.breakers.get_mut(&key) { breaker.record_success(); }
}
pub fn node_count(&self) -> usize { self.nodes.len() }
pub fn open_circuits(&self) -> usize { self.breakers.values().filter(|b| b.is_open).count() }
}
#[cfg(test)]
mod tests {
use super::*;
fn setup() -> OrbitalRouter {
let mut r = OrbitalRouter::new(3);
r.add_node(MeshNode { id: "a".into(), region: "sg".into(), latency_ms: 5, capacity: 100, current_load: 10 });
r.add_node(MeshNode { id: "b".into(), region: "jp".into(), latency_ms: 20, capacity: 100, current_load: 50 });
r.add_node(MeshNode { id: "c".into(), region: "de".into(), latency_ms: 10, capacity: 100, current_load: 20 });
r.add_edge(MeshEdge { from: "a".into(), to: "b".into(), latency_ms: 15, bandwidth_mbps: 100 });
r.add_edge(MeshEdge { from: "a".into(), to: "c".into(), latency_ms: 10, bandwidth_mbps: 100 });
r.add_edge(MeshEdge { from: "c".into(), to: "b".into(), latency_ms: 20, bandwidth_mbps: 50 });
r
}
#[test]
fn test_direct_route() { let mut r = setup(); let route = r.find_route("a", "b", 1000).unwrap(); assert_eq!(route, vec!["a", "b"]); }
#[test]
fn test_circuit_breaker() {
let mut r = setup();
r.report_failure("a", "b", 100);
r.report_failure("a", "b", 101);
r.report_failure("a", "b", 102);
assert_eq!(r.open_circuits(), 1);
}
}