From 897fa130282fbd3cf715ae8636761613a17679fc Mon Sep 17 00:00:00 2001 From: Michael Neale Date: Wed, 12 Nov 2025 12:27:06 +1100 Subject: [PATCH] cleaner --- crates/goose-server/src/commands/agent.rs | 8 +-- crates/goose-server/src/state.rs | 23 +------ crates/goose-server/src/tunnel/mod.rs | 74 +++++++++-------------- 3 files changed, 32 insertions(+), 73 deletions(-) diff --git a/crates/goose-server/src/commands/agent.rs b/crates/goose-server/src/commands/agent.rs index f1594ede6a..184dd288c6 100644 --- a/crates/goose-server/src/commands/agent.rs +++ b/crates/goose-server/src/commands/agent.rs @@ -57,14 +57,12 @@ pub async fn run() -> Result<()> { .layer(cors); let listener = tokio::net::TcpListener::bind(settings.socket_addr()).await?; - let local_addr = listener.local_addr()?; - info!("listening on {}", local_addr); + info!("listening on {}", listener.local_addr()?); - let app_state_clone = app_state.clone(); + let tunnel_manager = app_state.tunnel_manager.clone(); tokio::spawn(async move { - // a very short pause for goosed to start, I found without this, reconnections may struggle tokio::time::sleep(tokio::time::Duration::from_millis(100)).await; - app_state_clone.auto_start_tunnel().await; + tunnel_manager.check_auto_start().await; }); axum::serve(listener, app) diff --git a/crates/goose-server/src/state.rs b/crates/goose-server/src/state.rs index 36856862d2..f684eb6afb 100644 --- a/crates/goose-server/src/state.rs +++ b/crates/goose-server/src/state.rs @@ -22,9 +22,7 @@ pub struct AppState { impl AppState { pub async fn new() -> anyhow::Result> { let agent_manager = AgentManager::instance().await?; - // Initialize tunnel manager with default config - will lazy-load actual config when needed - // This prevents blocking server startup if keyring access requires password prompt - let tunnel_manager = Arc::new(TunnelManager::new_uninitialized()); + let tunnel_manager = Arc::new(TunnelManager::new()); Ok(Arc::new(Self { agent_manager, @@ -35,25 +33,6 @@ impl AppState { })) } - pub async fn auto_start_tunnel(&self) { - // Ensure config is loaded before checking status - self.tunnel_manager.ensure_initialized().await; - - let status = self.tunnel_manager.get_status().await; - - if status.auto_start && status.state == crate::tunnel::TunnelState::Idle { - tracing::info!("Auto-starting tunnel"); - match self.tunnel_manager.start().await { - Ok(info) => { - tracing::info!("Tunnel auto-started successfully: {}", info.url); - } - Err(e) => { - tracing::error!("Failed to auto-start tunnel: {}", e); - } - } - } - } - pub async fn scheduler(&self) -> Result, anyhow::Error> { self.agent_manager.scheduler().await } diff --git a/crates/goose-server/src/tunnel/mod.rs b/crates/goose-server/src/tunnel/mod.rs index cd1d1164b6..5392e1a322 100644 --- a/crates/goose-server/src/tunnel/mod.rs +++ b/crates/goose-server/src/tunnel/mod.rs @@ -55,58 +55,50 @@ pub struct TunnelStatus { pub struct TunnelManager { state: Arc>, info: Arc>>, - config: Arc>>, - config_initialized: Arc>, + config: Arc>, lapstone_handle: Arc>>>, restart_tx: Arc>>>, watchdog_handle: Arc>>>, } impl TunnelManager { - pub fn new(config: TunnelConfig) -> Self { + pub fn new() -> Self { TunnelManager { state: Arc::new(RwLock::new(TunnelState::Idle)), info: Arc::new(RwLock::new(None)), - config: Arc::new(RwLock::new(Some(config))), - config_initialized: Arc::new(RwLock::new(true)), + config: Arc::new(RwLock::new(TunnelConfig::default())), lapstone_handle: Arc::new(RwLock::new(None)), restart_tx: Arc::new(RwLock::new(None)), watchdog_handle: Arc::new(RwLock::new(None)), } } - pub fn new_uninitialized() -> Self { - TunnelManager { - state: Arc::new(RwLock::new(TunnelState::Idle)), - info: Arc::new(RwLock::new(None)), - config: Arc::new(RwLock::new(None)), - config_initialized: Arc::new(RwLock::new(false)), - lapstone_handle: Arc::new(RwLock::new(None)), - restart_tx: Arc::new(RwLock::new(None)), - watchdog_handle: Arc::new(RwLock::new(None)), - } + async fn load_config(&self) { + let loaded = config::load_config().await; + *self.config.write().await = loaded; } - pub async fn ensure_initialized(&self) { - let initialized = *self.config_initialized.read().await; - if !initialized { - let loaded_config = config::load_config().await; - *self.config.write().await = Some(loaded_config); - *self.config_initialized.write().await = true; + pub async fn check_auto_start(&self) { + self.load_config().await; + + let status = self.get_status().await; + if status.auto_start && status.state == TunnelState::Idle { + tracing::info!("Auto-starting tunnel"); + match self.start().await { + Ok(info) => { + tracing::info!("Tunnel auto-started successfully: {}", info.url); + } + Err(e) => { + tracing::error!("Failed to auto-start tunnel: {}", e); + } + } } } pub async fn get_status(&self) -> TunnelStatus { - self.ensure_initialized().await; let state = self.state.read().await.clone(); let info = self.info.read().await.clone(); - let auto_start = self - .config - .read() - .await - .as_ref() - .map(|c| c.auto_start) - .unwrap_or(false); + let auto_start = self.config.read().await.auto_start; TunnelStatus { state, info, @@ -118,19 +110,14 @@ impl TunnelManager { where F: FnOnce(&mut TunnelConfig), { - self.ensure_initialized().await; - let mut cfg_opt = self.config.write().await; - if let Some(cfg) = cfg_opt.as_mut() { - f(cfg); - if let Err(e) = config::save_config(cfg).await { - tracing::error!("Failed to save tunnel config: {}", e); - } + let mut cfg = self.config.write().await; + f(&mut cfg); + if let Err(e) = config::save_config(&cfg).await { + tracing::error!("Failed to save tunnel config: {}", e); } } pub async fn start(&self) -> anyhow::Result { - self.ensure_initialized().await; - let mut state = self.state.write().await; if *state != TunnelState::Idle { anyhow::bail!("Tunnel is already running or starting"); @@ -138,7 +125,7 @@ impl TunnelManager { *state = TunnelState::Starting; drop(state); - let config = self.config.read().await.clone().unwrap_or_default(); + let config = self.config.read().await.clone(); let server_port = get_server_port()?; let tunnel_secret = config.secret.clone().unwrap_or_else(generate_secret); @@ -179,12 +166,7 @@ impl TunnelManager { let watchdog = tokio::spawn(async move { while restart_rx.recv().await.is_some() { - let auto_start = config - .read() - .await - .as_ref() - .map(|c| c.auto_start) - .unwrap_or(false); + let auto_start = config.read().await.auto_start; if auto_start { tracing::warn!("Tunnel connection lost, initiating restart..."); @@ -194,7 +176,7 @@ impl TunnelManager { tokio::time::sleep(std::time::Duration::from_millis(100)).await; *state.write().await = TunnelState::Starting; - let cfg = config.read().await.clone().unwrap_or_default(); + let cfg = config.read().await.clone(); let tunnel_secret = cfg.secret.clone().unwrap_or_else(generate_secret); let server_secret = std::env::var("GOOSE_SERVER__SECRET_KEY") .unwrap_or_else(|_| "test".to_string());