use std::collections::HashMap;
use std::sync::Arc;
use std::time::{Duration, Instant};
use tokio::sync::{mpsc, Mutex};
pub struct MultiplexerConnection {
pub sender: mpsc::Sender<Vec<u8>>,
pub active_requests: Mutex<HashMap<String, mpsc::Sender<()>>>,
pub last_activity: Mutex<Instant>,
}
impl MultiplexerConnection {
pub async fn touch(&self) {
*self.last_activity.lock().await = Instant::now();
}
}
#[derive(Default)]
pub struct MultiplexerRegistry {
pub multiplexers: Mutex<HashMap<String, Arc<MultiplexerConnection>>>,
}
impl MultiplexerRegistry {
pub fn new() -> Self {
Self {
multiplexers: Mutex::new(HashMap::new()),
}
}
pub async fn add(
&self,
id: String,
sender: mpsc::Sender<Vec<u8>>,
) -> Arc<MultiplexerConnection> {
let conn = Arc::new(MultiplexerConnection {
sender,
active_requests: Mutex::new(HashMap::new()),
last_activity: Mutex::new(Instant::now()),
});
let mut multiplexers = self.multiplexers.lock().await;
multiplexers.insert(id, conn.clone());
conn
}
pub async fn remove(&self, id: &str) {
let mut multiplexers = self.multiplexers.lock().await;
multiplexers.remove(id);
}
pub async fn get(&self, id: &str) -> Option<Arc<MultiplexerConnection>> {
let multiplexers = self.multiplexers.lock().await;
let conn = multiplexers.get(id).cloned();
if let Some(ref c) = conn {
c.touch().await;
}
conn
}
pub async fn cleanup_stale(&self, timeout: Duration) {
let mut multiplexers = self.multiplexers.lock().await;
let now = Instant::now();
let mut to_remove = Vec::new();
for (id, conn) in multiplexers.iter() {
let last_activity = *conn.last_activity.lock().await;
if now.duration_since(last_activity) > timeout {
to_remove.push(id.clone());
}
}
for id in to_remove {
multiplexers.remove(&id);
}
}
}