use std::sync::Arc; use tokio::sync::Mutex; use crate::agent::AgentError; use super::session::Session; use super::session_factory::SessionFactory; use super::session_pool::SessionPool; #[derive(Clone)] pub(crate) struct SessionLifecycleService { session_pool: SessionPool, } impl SessionLifecycleService { pub(crate) fn new(session_factory: SessionFactory, session_ttl_hours: Option) -> Self { Self { session_pool: SessionPool::new(session_factory, session_ttl_hours), } } pub(crate) async fn ensure_session(&self, channel_name: &str) -> Result<(), AgentError> { self.session_pool.ensure_session(channel_name).await } pub(crate) async fn get(&self, channel_name: &str) -> Option>> { self.session_pool.get(channel_name).await } pub(crate) async fn touch(&self, channel_name: &str) { self.session_pool.touch(channel_name).await; } /// 获取活跃的主 Session(用于用户消息) pub(crate) async fn active_session( &self, channel_name: &str, ) -> Result>, AgentError> { self.ensure_session(channel_name).await?; self.touch(channel_name).await; self.get(channel_name) .await .ok_or_else(|| AgentError::Other("Session not found".to_string())) } /// 根据 chat_id 自动选择并获取 Session /// - scheduler/ 开头:返回定时任务专用 Session /// - 其他:返回主 Session pub(crate) async fn active_session_for_chat_id( &self, channel_name: &str, chat_id: &str, ) -> Result>, AgentError> { self.session_pool.ensure_session_for_chat_id(channel_name, chat_id).await?; self.touch(channel_name).await; self.session_pool.get_for_chat_id(channel_name, chat_id) .await .ok_or_else(|| AgentError::Other("Session not found".to_string())) } pub(crate) async fn cleanup_expired_sessions(&self) -> usize { self.session_pool.cleanup_expired_sessions().await } }