diff --git a/src-tauri/src/services/ws/user_status.rs b/src-tauri/src/services/ws/user_status.rs index 5222c20..3d6c387 100644 --- a/src-tauri/src/services/ws/user_status.rs +++ b/src-tauri/src/services/ws/user_status.rs @@ -1,12 +1,12 @@ +use once_cell::sync::Lazy; use rust_socketio::Payload; use tauri::async_runtime; +use tokio::sync::Mutex; +use tokio::task::JoinHandle; +use tokio::time::Duration; use tracing::error; -use crate::{ - lock_r, - services::health_manager::show_health_manager_with_error, - state::FDOLL, -}; +use crate::{lock_r, services::health_manager::show_health_manager_with_error, state::FDOLL}; use super::WS_EVENT; @@ -17,6 +17,9 @@ pub struct UserStatusPayload { pub state: String, } +static USER_STATUS_REPORT_DEBOUNCE: Lazy>>> = + Lazy::new(|| Mutex::new(None)); + pub async fn report_user_status(status: UserStatusPayload) { let payload_value = match serde_json::to_value(&status) { Ok(val) => val, @@ -38,34 +41,49 @@ pub async fn report_user_status(status: UserStatusPayload) { } }; - if let Some(client) = client_opt { - if !is_initialized { - return; + { + let mut debouncer = USER_STATUS_REPORT_DEBOUNCE.lock().await; + if let Some(handle) = debouncer.take() { + handle.abort(); } - - match async_runtime::spawn_blocking(move || { - client.emit( - WS_EVENT::CLIENT_REPORT_USER_STATUS, - Payload::Text(vec![payload_value]), - ) - }) - .await - { - Ok(Ok(_)) => (), - Ok(Err(e)) => { - error!("Failed to emit user status report: {}", e); - show_health_manager_with_error(Some(format!( - "WebSocket emit failed: {}", - e - ))); + let payload_value_clone = payload_value.clone(); + let client_opt_clone = client_opt.clone(); + let is_initialized_clone = is_initialized; + let handle = tokio::spawn(async move { + tokio::time::sleep(Duration::from_millis(500)).await; + if let Some(client) = client_opt_clone { + if !is_initialized_clone { + return; + } + match async_runtime::spawn_blocking(move || { + client.emit( + WS_EVENT::CLIENT_REPORT_USER_STATUS, + Payload::Text(vec![payload_value_clone]), + ) + }) + .await + { + Ok(Ok(_)) => (), + Ok(Err(e)) => { + error!("Failed to emit user status report: {}", e); + show_health_manager_with_error(Some(format!( + "WebSocket emit failed: {}", + e + ))); + } + Err(e) => { + error!( + "Failed to execute blocking task for user status report: {}", + e + ); + show_health_manager_with_error(Some(format!( + "WebSocket task failed: {}", + e + ))); + } + } } - Err(e) => { - error!("Failed to execute blocking task for user status report: {}", e); - show_health_manager_with_error(Some(format!( - "WebSocket task failed: {}", - e - ))); - } - } + }); + *debouncer = Some(handle); } }