From 384ccda5159fab08a72710e76dfe8cbecd50e7d0 Mon Sep 17 00:00:00 2001 From: Valentin Haudiquet Date: Fri, 5 Jun 2026 21:17:15 +0200 Subject: [PATCH] tryfix: reconnect to league client --- record-daemon/src/lqp/client.rs | 38 ++++++++++++++++++++++++++------- record-daemon/src/main.rs | 8 +++---- 2 files changed, 34 insertions(+), 12 deletions(-) diff --git a/record-daemon/src/lqp/client.rs b/record-daemon/src/lqp/client.rs index afce1bf..a426e09 100644 --- a/record-daemon/src/lqp/client.rs +++ b/record-daemon/src/lqp/client.rs @@ -31,6 +31,8 @@ pub struct LqpClient { shutdown: Arc>, /// Last emitted game ID for deduplication of GameStart events. last_emitted_game_id: Arc>>, + /// WebSocket connection state (true if WebSocket is connected). + ws_connected: Arc>, } impl LqpClient { @@ -50,6 +52,7 @@ impl LqpClient { http_client, shutdown: Arc::new(RwLock::new(false)), last_emitted_game_id: Arc::new(RwLock::new(None)), + ws_connected: Arc::new(RwLock::new(false)), } } @@ -63,12 +66,20 @@ impl LqpClient { self.state.read().await.clone() } - /// Check if connected to League Client. + /// Check if connected to League Client (has valid credentials). pub async fn is_connected(&self) -> bool { self.credentials.read().await.is_some() } + /// Check if WebSocket is connected. + pub async fn is_ws_connected(&self) -> bool { + *self.ws_connected.read().await + } + /// Connect to the League Client with the given credentials. + /// + /// This only stores credentials and verifies basic connectivity. + /// The actual WebSocket connection is established in start_event_listener(). pub async fn connect(&self, creds: LockfileCredentials) -> Result<()> { info!("Connecting to League Client at port {}", creds.port); @@ -85,12 +96,13 @@ impl LqpClient { info!("Connected to League Client, current phase: {:?}", phase); } Err(e) => { - warn!("Failed to verify connection: {}", e); - // Still consider connected, WebSocket might work + warn!("Failed to verify connection via REST API: {}", e); + // REST API might not be ready yet, but WebSocket could work + // Don't fail here - let start_event_listener() try the WebSocket } } - // Fetch local player's puuid for champion extraction + // Fetch local player's puuid for champion extraction (best effort) if let Ok(summoner) = self.get_summoner().await { if let Some(puuid) = summoner.get("puuid").and_then(|p| p.as_str()) { self.state.write().await.local_puuid = Some(puuid.to_string()); @@ -104,6 +116,7 @@ impl LqpClient { /// Disconnect from the League Client. pub async fn disconnect(&self) { *self.shutdown.write().await = true; + *self.ws_connected.write().await = false; *self.credentials.write().await = None; *self.state.write().await = ClientState::default(); *self.last_emitted_game_id.write().await = None; @@ -167,12 +180,16 @@ impl LqpClient { } info!("All subscriptions sent"); + // Mark WebSocket as connected + *self.ws_connected.write().await = true; + // Clone references for the async block let event_sender = self.event_sender.clone(); let state = self.state.clone(); let shutdown = self.shutdown.clone(); let credentials = self.credentials.clone(); let last_emitted_game_id = self.last_emitted_game_id.clone(); + let ws_connected = self.ws_connected.clone(); // Spawn the message handler tokio::spawn(async move { @@ -296,9 +313,10 @@ impl LqpClient { } } - // Clear credentials on disconnect + // Clear connection state on disconnect + *ws_connected.write().await = false; *credentials.write().await = None; - debug!("WebSocket listener ended"); + info!("WebSocket listener ended"); }); Ok(()) @@ -503,12 +521,16 @@ impl LqpClient { info!("Starting live client event poller"); tokio::spawn(async move { + // Small delay to ensure connection is stable + tokio::time::sleep(tokio::time::Duration::from_millis(100)).await; + let mut last_event_id: Option = None; let mut poll_count = 0u32; loop { - if *shutdown.read().await { - info!("Live client event poller shutting down"); + let is_shutdown = *shutdown.read().await; + if is_shutdown { + info!("Live client event poller shutting down (shutdown flag is true)"); break; } diff --git a/record-daemon/src/main.rs b/record-daemon/src/main.rs index 495b7fe..b35ae74 100644 --- a/record-daemon/src/main.rs +++ b/record-daemon/src/main.rs @@ -242,9 +242,9 @@ impl Daemon { } None => { // No change in lockfile status - // Check if we need to reconnect (lockfile exists but not connected) - if watcher.credentials().is_some() && !self.lqp_client.is_connected().await { - debug!("Lockfile exists but not connected, attempting reconnect..."); + // Check if we need to reconnect (lockfile exists but WebSocket not connected) + if watcher.credentials().is_some() && !self.lqp_client.is_ws_connected().await { + info!("Lockfile exists but WebSocket not connected, attempting reconnect..."); if let Some(creds) = watcher.credentials() { match self.lqp_client.connect(creds.clone()).await { Ok(()) => { @@ -261,7 +261,7 @@ impl Daemon { } } Err(e) => { - debug!("Reconnect attempt failed: {}", e); + info!("Reconnect attempt failed: {}", e); // Will retry on next check } }