PicoBot/src/gateway/session_lifecycle.rs
oudecheng 4b93c84447 test(gateway): 定时任务 topic 补齐与消息送达回归测试
- 新增捕获请求的 mock OpenAI server,直接断言任务 prompt 进入 LLM 输入

- 静默任务按生产默认 fresh_session=true 连续执行两轮,验证清空-重建时序下 prompt 仍送达、topic 自动创建并持久化、系统提示词含送达提示

- ensure_topic_for_chat 幂等性与全新 chat 默认 topic 创建测试

- append_persisted_message 无 topic 回退 chat_id 键内存历史测试

- SessionManager/SessionLifecycleService 暴露 get_scheduler_session 供测试断言
2026-08-15 18:17:29 +08:00

77 lines
2.4 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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<u64>) -> 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<Arc<Mutex<Session>>> {
self.session_pool.get(channel_name).await
}
/// 获取定时任务专用 Session不自动创建
pub(crate) async fn get_scheduler_session(
&self,
channel_name: &str,
) -> Option<Arc<Mutex<Session>>> {
self.session_pool.get_scheduler_session(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<Arc<Mutex<Session>>, 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<Arc<Mutex<Session>>, 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
}
}