77 lines
2.1 KiB
Rust
77 lines
2.1 KiB
Rust
use std::collections::HashMap;
|
|
use std::sync::Arc;
|
|
use std::time::Instant;
|
|
|
|
use tokio::sync::{Mutex, mpsc};
|
|
|
|
use crate::agent::AgentError;
|
|
use crate::protocol::WsOutbound;
|
|
|
|
use super::session::Session;
|
|
use super::session_factory::SessionFactory;
|
|
|
|
#[derive(Clone)]
|
|
pub(crate) struct SessionPool {
|
|
inner: Arc<Mutex<SessionPoolInner>>,
|
|
session_factory: SessionFactory,
|
|
}
|
|
|
|
struct SessionPoolInner {
|
|
sessions: HashMap<String, Arc<Mutex<Session>>>,
|
|
session_timestamps: HashMap<String, Instant>,
|
|
}
|
|
|
|
impl SessionPool {
|
|
pub(crate) fn new(session_factory: SessionFactory) -> Self {
|
|
Self {
|
|
inner: Arc::new(Mutex::new(SessionPoolInner {
|
|
sessions: HashMap::new(),
|
|
session_timestamps: HashMap::new(),
|
|
})),
|
|
session_factory,
|
|
}
|
|
}
|
|
|
|
pub(crate) async fn ensure_session(&self, channel_name: &str) -> Result<(), AgentError> {
|
|
let mut inner = self.inner.lock().await;
|
|
|
|
// 简化:只检查 session 是否存在,不做超时判断
|
|
if inner.sessions.contains_key(channel_name) {
|
|
return Ok(());
|
|
}
|
|
|
|
// Session 不存在则创建
|
|
let (user_tx, _rx) = mpsc::channel::<WsOutbound>(100);
|
|
let session = self
|
|
.session_factory
|
|
.create(channel_name.to_string(), user_tx)
|
|
.await?;
|
|
|
|
inner
|
|
.sessions
|
|
.insert(channel_name.to_string(), Arc::new(Mutex::new(session)));
|
|
inner
|
|
.session_timestamps
|
|
.insert(channel_name.to_string(), Instant::now());
|
|
|
|
Ok(())
|
|
}
|
|
|
|
pub(crate) async fn get(&self, channel_name: &str) -> Option<Arc<Mutex<Session>>> {
|
|
self.inner.lock().await.sessions.get(channel_name).cloned()
|
|
}
|
|
|
|
pub(crate) async fn touch(&self, channel_name: &str) {
|
|
self.inner
|
|
.lock()
|
|
.await
|
|
.session_timestamps
|
|
.insert(channel_name.to_string(), Instant::now());
|
|
}
|
|
|
|
pub(crate) async fn cleanup_expired_sessions(&self) -> usize {
|
|
// Session 级别不再自动清理,返回 0
|
|
0
|
|
}
|
|
}
|