refactor(stats): streamline session management in RemoteStatsSampler (#545)
- Removed the dependency on RemoteStatsSampler in the close_session function. - Introduced session locking mechanism to prevent race conditions when fetching remote stats. - Updated the stats fetching logic to utilize a probe plan for better efficiency. - Enhanced the RemoteStatsSampler to manage session states and ensure proper cleanup of session data.
This commit is contained in:
1 parent
c556b16aa6
commit
f4e8b499f6
4 files changed
+732
-184
No files matched your search
@@ -1,5 +1,4 @@
|
||||
use crate::config;
|
||||
use crate::core::monitoring::stats::RemoteStatsSampler;
|
||||
use crate::core::ssh::{
|
||||
self, HostKeyVerifyManager, PendingAuthManager, PendingSshAgentAuthManager,
|
||||
PendingSshAuthManager, SshAgentAuthAction, SshAuthResponse,
|
||||
@@ -1081,7 +1080,6 @@ pub async fn detach_session_renderer(
|
||||
pub async fn close_session(
|
||||
app: tauri::AppHandle,
|
||||
state: tauri::State<'_, Arc<SessionManager>>,
|
||||
stats_sampler: tauri::State<'_, Arc<RemoteStatsSampler>>,
|
||||
session_id: String,
|
||||
) -> AppResult<()> {
|
||||
let session_id_clone = session_id.clone();
|
||||
@@ -1102,8 +1100,6 @@ pub async fn close_session(
|
||||
other => other,
|
||||
};
|
||||
|
||||
stats_sampler.clear_session(&session_id).await;
|
||||
|
||||
// Concurrently tidy up any downloaded/watcher temporary files stored in the OS temp directory
|
||||
tauri::async_runtime::spawn(async move {
|
||||
if let Ok(temp_dir) = app.path().temp_dir() {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use crate::core::SessionManager;
|
||||
use crate::core::monitoring::stats::{
|
||||
RemoteStats, RemoteStatsSampler, SYSINFO_SCRIPT, parse_stats_output,
|
||||
RemoteStats, RemoteStatsSampler, build_stats_script, parse_stats_output,
|
||||
};
|
||||
use crate::core::remote_exec::{ensure_success, exec_ssh_session_command};
|
||||
use crate::error::{AppError, AppResult};
|
||||
@@ -13,6 +13,15 @@ pub async fn get_remote_stats(
|
||||
sampler: tauri::State<'_, Arc<RemoteStatsSampler>>,
|
||||
session_id: String,
|
||||
) -> AppResult<RemoteStats> {
|
||||
// Auto-icon detection and the monitor can request the same new session concurrently.
|
||||
// Serializing per session avoids duplicate static/disk probes without blocking other hosts.
|
||||
let lease = sampler.lock_session(&session_id).await;
|
||||
if !lease.is_current() {
|
||||
return Err(AppError::SessionNotFound(format!(
|
||||
"Session '{session_id}' was closed while waiting for remote stats"
|
||||
)));
|
||||
}
|
||||
|
||||
let remote_stats_enabled = {
|
||||
let sessions = state.sessions.lock().await;
|
||||
let session = sessions.get(&session_id).ok_or_else(|| {
|
||||
@@ -26,17 +35,22 @@ pub async fn get_remote_stats(
|
||||
));
|
||||
}
|
||||
|
||||
let probe_plan = sampler.probe_plan(&session_id).await;
|
||||
let script = build_stats_script(probe_plan);
|
||||
|
||||
let output = exec_ssh_session_command(
|
||||
state.inner(),
|
||||
&session_id,
|
||||
SYSINFO_SCRIPT.as_bytes(),
|
||||
script.as_bytes(),
|
||||
Duration::from_secs(15),
|
||||
)
|
||||
.await?;
|
||||
let output = ensure_success(output, "Failed to fetch stats")?;
|
||||
let parsed = parse_stats_output(&output.stdout)?;
|
||||
|
||||
Ok(sampler.complete_snapshot(&session_id, parsed).await)
|
||||
Ok(sampler
|
||||
.complete_snapshot_with_lease(&session_id, &lease, parsed)
|
||||
.await)
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
@@ -4,6 +4,7 @@ use super::client::{
|
||||
use crate::config::SftpCwdFollowMode;
|
||||
use crate::core::capture::OutputCaptureProcessor;
|
||||
use crate::core::input::remap_del_to_bs;
|
||||
use crate::core::monitoring::stats::RemoteStatsSampler;
|
||||
use crate::core::ssh::osc::{self, OscStripper, ShellKind};
|
||||
use crate::core::terminal_session::local::split_startup_passthrough;
|
||||
use crate::core::terminal_session::{TerminalOutputDecoder, encode_terminal_input};
|
||||
@@ -1611,6 +1612,9 @@ pub(super) async fn ssh_io_loop(
|
||||
}
|
||||
|
||||
manager.remove_session(&session_id).await;
|
||||
if let Some(stats_sampler) = app.try_state::<Arc<RemoteStatsSampler>>() {
|
||||
stats_sampler.clear_session(&session_id).await;
|
||||
}
|
||||
|
||||
if let Some(ref conn_id) = connection_id {
|
||||
if let Some(tunnel_mgr) = app.try_state::<Arc<super::TunnelManager>>() {
|
||||
|
||||
Reference in new issue
Block a user