Change summary
crates/zed/src/reliability.rs | 44 +++++++++++++++++++++++++++++++++++++
1 file changed, 44 insertions(+)
Detailed changes
@@ -16,6 +16,8 @@ use util::ResultExt;
use crate::STARTUP_TIME;
+const MAX_HANG_TRACES: usize = 3;
+
pub fn init(client: Arc<Client>, cx: &mut App) {
monitor_hangs(cx);
@@ -82,6 +84,8 @@ fn monitor_hangs(cx: &App) {
.spawn({
let background_executor = background_executor.clone();
async move {
+ cleanup_old_hang_traces();
+
let mut hang_time = None;
let mut hanging = false;
@@ -115,6 +119,27 @@ fn monitor_hangs(cx: &App) {
.detach();
}
+fn cleanup_old_hang_traces() {
+ if let Ok(entries) = std::fs::read_dir(paths::hang_traces_dir()) {
+ let mut files: Vec<_> = entries
+ .filter_map(|entry| entry.ok())
+ .filter(|entry| {
+ entry
+ .path()
+ .extension()
+ .is_some_and(|ext| ext == "miniprof")
+ })
+ .collect();
+
+ if files.len() > MAX_HANG_TRACES {
+ files.sort_by_key(|entry| entry.file_name());
+ for entry in files.iter().take(files.len() - MAX_HANG_TRACES) {
+ std::fs::remove_file(entry.path()).log_err();
+ }
+ }
+ }
+}
+
fn save_hang_trace(
main_thread_id: ThreadId,
background_executor: &gpui::BackgroundExecutor,
@@ -144,6 +169,25 @@ fn save_hang_trace(
return;
};
+ if let Ok(entries) = std::fs::read_dir(paths::hang_traces_dir()) {
+ let mut files: Vec<_> = entries
+ .filter_map(|entry| entry.ok())
+ .filter(|entry| {
+ entry
+ .path()
+ .extension()
+ .is_some_and(|ext| ext == "miniprof")
+ })
+ .collect();
+
+ if files.len() >= MAX_HANG_TRACES {
+ files.sort_by_key(|entry| entry.file_name());
+ for entry in files.iter().take(files.len() - (MAX_HANG_TRACES - 1)) {
+ std::fs::remove_file(entry.path()).log_err();
+ }
+ }
+ }
+
std::fs::write(&trace_path, timings)
.context("hang trace file writing")
.log_err();