63 lines
2.2 KiB
Rust
63 lines
2.2 KiB
Rust
//! [TSM.ID].[11031972] — Platform X Ecosystem
|
|
//! IPC Router with priority-based message routing
|
|
|
|
use crate::{IpcMessage, IpcError, Result};
|
|
use std::collections::{BinaryHeap, HashMap};
|
|
use std::cmp::Ordering;
|
|
use std::sync::{Arc, Mutex};
|
|
|
|
#[derive(Eq, PartialEq)]
|
|
struct PriorityMessage { msg: Vec<u8>, priority: u8, seq: u64 }
|
|
|
|
impl Ord for PriorityMessage {
|
|
fn cmp(&self, other: &Self) -> Ordering {
|
|
self.priority.cmp(&other.priority).then_with(|| other.seq.cmp(&self.seq))
|
|
}
|
|
}
|
|
impl PartialOrd for PriorityMessage {
|
|
fn partial_cmp(&self, other: &Self) -> Option<Ordering> { Some(self.cmp(other)) }
|
|
}
|
|
|
|
pub struct IpcRouter {
|
|
routes: Arc<Mutex<HashMap<String, String>>>,
|
|
priority_queue: Arc<Mutex<BinaryHeap<PriorityMessage>>>,
|
|
seq: Arc<Mutex<u64>>,
|
|
max_queue: usize,
|
|
}
|
|
|
|
impl IpcRouter {
|
|
pub fn new(max_queue: usize) -> Self {
|
|
Self {
|
|
routes: Arc::new(Mutex::new(HashMap::new())),
|
|
priority_queue: Arc::new(Mutex::new(BinaryHeap::new())),
|
|
seq: Arc::new(Mutex::new(0)),
|
|
max_queue,
|
|
}
|
|
}
|
|
|
|
pub fn add_route(&self, source: &str, target: &str) -> Result<()> {
|
|
let mut r = self.routes.lock().map_err(|e| IpcError::LockPoisoned(e.to_string()))?;
|
|
r.insert(source.to_string(), target.to_string());
|
|
Ok(())
|
|
}
|
|
|
|
pub fn resolve(&self, source: &str) -> Result<String> {
|
|
let r = self.routes.lock().map_err(|e| IpcError::LockPoisoned(e.to_string()))?;
|
|
r.get(source).cloned().ok_or_else(|| IpcError::ChannelNotFound(source.to_string()))
|
|
}
|
|
|
|
pub fn enqueue(&self, msg: IpcMessage) -> Result<()> {
|
|
let mut pq = self.priority_queue.lock().map_err(|e| IpcError::LockPoisoned(e.to_string()))?;
|
|
if pq.len() >= self.max_queue { return Err(IpcError::BufferFull); }
|
|
let mut s = self.seq.lock().map_err(|e| IpcError::LockPoisoned(e.to_string()))?;
|
|
*s += 1;
|
|
pq.push(PriorityMessage { msg: msg.payload, priority: msg.priority, seq: *s });
|
|
Ok(())
|
|
}
|
|
|
|
pub fn dequeue(&self) -> Result<Option<Vec<u8>>> {
|
|
let mut pq = self.priority_queue.lock().map_err(|e| IpcError::LockPoisoned(e.to_string()))?;
|
|
Ok(pq.pop().map(|pm| pm.msg))
|
|
}
|
|
}
|