make agent manager singleton (#4880)

This commit is contained in:
Yingjie He
2025-09-29 13:09:55 -07:00
committed by GitHub
parent 41d32c04b1
commit 1c424303c2
3 changed files with 95 additions and 62 deletions
+29 -3
View File
@@ -12,9 +12,13 @@ use etcetera::{choose_app_strategy, AppStrategy};
use lru::LruCache;
use std::num::NonZeroUsize;
use std::sync::Arc;
use tokio::sync::RwLock;
use tokio::sync::{OnceCell, RwLock};
use tracing::{debug, info, warn};
const DEFAULT_MAX_SESSION: usize = 100;
static AGENT_MANAGER: OnceCell<Arc<AgentManager>> = OnceCell::const_new();
pub struct AgentManager {
sessions: Arc<RwLock<LruCache<String, Arc<Agent>>>>,
scheduler: Arc<dyn SchedulerTrait>,
@@ -22,7 +26,19 @@ pub struct AgentManager {
}
impl AgentManager {
pub async fn new(max_sessions: Option<usize>) -> Result<Self> {
/// Reset the global singleton - ONLY for testing
pub fn reset_for_test() {
unsafe {
// Cast away the const to get mutable access
// This is safe in test context where we control execution with #[serial]
let cell_ptr = &AGENT_MANAGER as *const OnceCell<Arc<AgentManager>>
as *mut OnceCell<Arc<AgentManager>>;
let _ = (*cell_ptr).take();
}
}
// Private constructor - prevents direct instantiation in production
async fn new(max_sessions: Option<usize>) -> Result<Self> {
// Construct scheduler with the standard goose-server path
let schedule_file_path = choose_app_strategy(APP_STRATEGY.clone())?
.data_dir()
@@ -30,7 +46,7 @@ impl AgentManager {
let scheduler = SchedulerFactory::create(schedule_file_path).await?;
let capacity = NonZeroUsize::new(max_sessions.unwrap_or(100))
let capacity = NonZeroUsize::new(max_sessions.unwrap_or(DEFAULT_MAX_SESSION))
.unwrap_or_else(|| NonZeroUsize::new(100).unwrap());
let manager = Self {
@@ -44,6 +60,16 @@ impl AgentManager {
Ok(manager)
}
pub async fn instance() -> Result<Arc<Self>> {
AGENT_MANAGER
.get_or_try_init(|| async {
let manager = Self::new(Some(DEFAULT_MAX_SESSION)).await?;
Ok(Arc::new(manager))
})
.await
.cloned()
}
pub async fn scheduler(&self) -> Result<Arc<dyn SchedulerTrait>> {
Ok(Arc::clone(&self.scheduler))
}