tryfix: reconnect to league client
record-daemon / Build, check and test (push) Failing after 10m47s

This commit is contained in:
2026-06-05 21:17:15 +02:00
parent 1c1b9c4d1a
commit 384ccda515
2 changed files with 34 additions and 12 deletions
+30 -8
View File
@@ -31,6 +31,8 @@ pub struct LqpClient {
shutdown: Arc<RwLock<bool>>, shutdown: Arc<RwLock<bool>>,
/// Last emitted game ID for deduplication of GameStart events. /// Last emitted game ID for deduplication of GameStart events.
last_emitted_game_id: Arc<RwLock<Option<u64>>>, last_emitted_game_id: Arc<RwLock<Option<u64>>>,
/// WebSocket connection state (true if WebSocket is connected).
ws_connected: Arc<RwLock<bool>>,
} }
impl LqpClient { impl LqpClient {
@@ -50,6 +52,7 @@ impl LqpClient {
http_client, http_client,
shutdown: Arc::new(RwLock::new(false)), shutdown: Arc::new(RwLock::new(false)),
last_emitted_game_id: Arc::new(RwLock::new(None)), 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() 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 { pub async fn is_connected(&self) -> bool {
self.credentials.read().await.is_some() 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. /// 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<()> { pub async fn connect(&self, creds: LockfileCredentials) -> Result<()> {
info!("Connecting to League Client at port {}", creds.port); info!("Connecting to League Client at port {}", creds.port);
@@ -85,12 +96,13 @@ impl LqpClient {
info!("Connected to League Client, current phase: {:?}", phase); info!("Connected to League Client, current phase: {:?}", phase);
} }
Err(e) => { Err(e) => {
warn!("Failed to verify connection: {}", e); warn!("Failed to verify connection via REST API: {}", e);
// Still consider connected, WebSocket might work // 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 Ok(summoner) = self.get_summoner().await {
if let Some(puuid) = summoner.get("puuid").and_then(|p| p.as_str()) { if let Some(puuid) = summoner.get("puuid").and_then(|p| p.as_str()) {
self.state.write().await.local_puuid = Some(puuid.to_string()); self.state.write().await.local_puuid = Some(puuid.to_string());
@@ -104,6 +116,7 @@ impl LqpClient {
/// Disconnect from the League Client. /// Disconnect from the League Client.
pub async fn disconnect(&self) { pub async fn disconnect(&self) {
*self.shutdown.write().await = true; *self.shutdown.write().await = true;
*self.ws_connected.write().await = false;
*self.credentials.write().await = None; *self.credentials.write().await = None;
*self.state.write().await = ClientState::default(); *self.state.write().await = ClientState::default();
*self.last_emitted_game_id.write().await = None; *self.last_emitted_game_id.write().await = None;
@@ -167,12 +180,16 @@ impl LqpClient {
} }
info!("All subscriptions sent"); info!("All subscriptions sent");
// Mark WebSocket as connected
*self.ws_connected.write().await = true;
// Clone references for the async block // Clone references for the async block
let event_sender = self.event_sender.clone(); let event_sender = self.event_sender.clone();
let state = self.state.clone(); let state = self.state.clone();
let shutdown = self.shutdown.clone(); let shutdown = self.shutdown.clone();
let credentials = self.credentials.clone(); let credentials = self.credentials.clone();
let last_emitted_game_id = self.last_emitted_game_id.clone(); let last_emitted_game_id = self.last_emitted_game_id.clone();
let ws_connected = self.ws_connected.clone();
// Spawn the message handler // Spawn the message handler
tokio::spawn(async move { 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; *credentials.write().await = None;
debug!("WebSocket listener ended"); info!("WebSocket listener ended");
}); });
Ok(()) Ok(())
@@ -503,12 +521,16 @@ impl LqpClient {
info!("Starting live client event poller"); info!("Starting live client event poller");
tokio::spawn(async move { 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<u64> = None; let mut last_event_id: Option<u64> = None;
let mut poll_count = 0u32; let mut poll_count = 0u32;
loop { loop {
if *shutdown.read().await { let is_shutdown = *shutdown.read().await;
info!("Live client event poller shutting down"); if is_shutdown {
info!("Live client event poller shutting down (shutdown flag is true)");
break; break;
} }
+4 -4
View File
@@ -242,9 +242,9 @@ impl Daemon {
} }
None => { None => {
// No change in lockfile status // No change in lockfile status
// Check if we need to reconnect (lockfile exists but not connected) // Check if we need to reconnect (lockfile exists but WebSocket not connected)
if watcher.credentials().is_some() && !self.lqp_client.is_connected().await { if watcher.credentials().is_some() && !self.lqp_client.is_ws_connected().await {
debug!("Lockfile exists but not connected, attempting reconnect..."); info!("Lockfile exists but WebSocket not connected, attempting reconnect...");
if let Some(creds) = watcher.credentials() { if let Some(creds) = watcher.credentials() {
match self.lqp_client.connect(creds.clone()).await { match self.lqp_client.connect(creds.clone()).await {
Ok(()) => { Ok(()) => {
@@ -261,7 +261,7 @@ impl Daemon {
} }
} }
Err(e) => { Err(e) => {
debug!("Reconnect attempt failed: {}", e); info!("Reconnect attempt failed: {}", e);
// Will retry on next check // Will retry on next check
} }
} }