mirror of
https://github.com/block/goose.git
synced 2026-07-17 12:56:20 +02:00
cleaner
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -22,9 +22,7 @@ pub struct AppState {
|
||||
impl AppState {
|
||||
pub async fn new() -> anyhow::Result<Arc<AppState>> {
|
||||
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<Arc<dyn SchedulerTrait>, anyhow::Error> {
|
||||
self.agent_manager.scheduler().await
|
||||
}
|
||||
|
||||
@@ -55,58 +55,50 @@ pub struct TunnelStatus {
|
||||
pub struct TunnelManager {
|
||||
state: Arc<RwLock<TunnelState>>,
|
||||
info: Arc<RwLock<Option<TunnelInfo>>>,
|
||||
config: Arc<RwLock<Option<TunnelConfig>>>,
|
||||
config_initialized: Arc<RwLock<bool>>,
|
||||
config: Arc<RwLock<TunnelConfig>>,
|
||||
lapstone_handle: Arc<RwLock<Option<tokio::task::JoinHandle<()>>>>,
|
||||
restart_tx: Arc<RwLock<Option<mpsc::Sender<()>>>>,
|
||||
watchdog_handle: Arc<RwLock<Option<tokio::task::JoinHandle<()>>>>,
|
||||
}
|
||||
|
||||
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<TunnelInfo> {
|
||||
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());
|
||||
|
||||
Reference in New Issue
Block a user