Don't iterate over all system processes (#11281)

Release Notes:

- Fixed a UI beachball when gathering process information
This commit is contained in:
Conrad Irwin 2024-05-01 20:08:56 -06:00 committed by GitHub
parent 3b5fd4ea66
commit b487f2ce6f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 38 additions and 34 deletions

View file

@ -12,7 +12,7 @@ use settings::{Settings, SettingsStore};
use sha2::{Digest, Sha256}; use sha2::{Digest, Sha256};
use std::io::Write; use std::io::Write;
use std::{env, mem, path::PathBuf, sync::Arc, time::Duration}; use std::{env, mem, path::PathBuf, sync::Arc, time::Duration};
use sysinfo::{CpuRefreshKind, MemoryRefreshKind, Pid, ProcessRefreshKind, RefreshKind, System}; use sysinfo::{CpuRefreshKind, Pid, ProcessRefreshKind, RefreshKind, System};
use telemetry_events::{ use telemetry_events::{
ActionEvent, AppEvent, AssistantEvent, AssistantKind, CallEvent, CopilotEvent, CpuEvent, ActionEvent, AppEvent, AssistantEvent, AssistantKind, CallEvent, CopilotEvent, CpuEvent,
EditEvent, EditorEvent, Event, EventRequestBody, EventWrapper, ExtensionEvent, MemoryEvent, EditEvent, EditorEvent, Event, EventRequestBody, EventWrapper, ExtensionEvent, MemoryEvent,
@ -171,17 +171,15 @@ impl Telemetry {
drop(state); drop(state);
let this = self.clone(); let this = self.clone();
cx.spawn(|_| async move { cx.background_executor()
// Avoiding calling `System::new_all()`, as there have been crashes related to it .spawn(async move {
let refresh_kind = RefreshKind::new() let mut system = System::new_with_specifics(
.with_memory(MemoryRefreshKind::everything()) // For memory usage RefreshKind::new().with_cpu(CpuRefreshKind::everything()),
.with_processes(ProcessRefreshKind::everything()) // For process usage );
.with_cpu(CpuRefreshKind::everything()); // For core count
let mut system = System::new_with_specifics(refresh_kind); let refresh_kind = ProcessRefreshKind::new().with_cpu().with_memory();
let current_process = Pid::from_u32(std::process::id());
// Avoiding calling `refresh_all()`, just update what we need system.refresh_process_specifics(current_process, refresh_kind);
system.refresh_specifics(refresh_kind);
// Waiting some amount of time before the first query is important to get a reasonable value // Waiting some amount of time before the first query is important to get a reasonable value
// https://docs.rs/sysinfo/0.29.10/sysinfo/trait.ProcessExt.html#tymethod.cpu_usage // https://docs.rs/sysinfo/0.29.10/sysinfo/trait.ProcessExt.html#tymethod.cpu_usage
@ -190,12 +188,12 @@ impl Telemetry {
loop { loop {
smol::Timer::after(DURATION_BETWEEN_SYSTEM_EVENTS).await; smol::Timer::after(DURATION_BETWEEN_SYSTEM_EVENTS).await;
system.refresh_specifics(refresh_kind);
let current_process = Pid::from_u32(std::process::id()); let current_process = Pid::from_u32(std::process::id());
let Some(process) = system.processes().get(&current_process) else { system.refresh_process_specifics(current_process, refresh_kind);
let process = current_process; let Some(process) = system.process(current_process) else {
log::error!("Failed to find own process {process:?} in system process table"); log::error!(
"Failed to find own process {current_process:?} in system process table"
);
// TODO: Fire an error telemetry event // TODO: Fire an error telemetry event
return; return;
}; };

View file

@ -98,8 +98,14 @@ impl PtyProcessInfo {
fn refresh(&mut self) -> Option<&Process> { fn refresh(&mut self) -> Option<&Process> {
let pid = self.pid_getter.pid()?; let pid = self.pid_getter.pid()?;
self.system.refresh_processes_specifics(self.refresh_kind); if self
.system
.refresh_process_specifics(pid, self.refresh_kind)
{
self.system.process(pid) self.system.process(pid)
} else {
None
}
} }
fn load(&mut self) -> Option<ProcessInfo> { fn load(&mut self) -> Option<ProcessInfo> {