tryfix: reconnect to league client
record-daemon / Build, check and test (push) Failing after 10m47s
record-daemon / Build, check and test (push) Failing after 10m47s
This commit is contained in:
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user