From a23e05c20b0c39bcaf000e5c937e1daa358eecbe Mon Sep 17 00:00:00 2001 From: Julia Date: Thu, 26 Oct 2023 17:16:04 +0200 Subject: [PATCH] Limit language server reinstallation attempts zed2 electric boogaloo --- crates/language2/src/language2.rs | 4 ++- crates/project2/src/project2.rs | 46 +++++++++++++++++++------------ 2 files changed, 32 insertions(+), 18 deletions(-) diff --git a/crates/language2/src/language2.rs b/crates/language2/src/language2.rs index 0a267e5e1a..89e98e57ca 100644 --- a/crates/language2/src/language2.rs +++ b/crates/language2/src/language2.rs @@ -37,7 +37,7 @@ use std::{ path::{Path, PathBuf}, str, sync::{ - atomic::{AtomicUsize, Ordering::SeqCst}, + atomic::{AtomicU64, AtomicUsize, Ordering::SeqCst}, Arc, }, }; @@ -115,6 +115,7 @@ pub struct CachedLspAdapter { pub disk_based_diagnostics_progress_token: Option, pub language_ids: HashMap, pub adapter: Arc, + pub reinstall_attempt_count: AtomicU64, } impl CachedLspAdapter { @@ -135,6 +136,7 @@ impl CachedLspAdapter { disk_based_diagnostics_progress_token, language_ids, adapter, + reinstall_attempt_count: AtomicU64::new(0), }) } diff --git a/crates/project2/src/project2.rs b/crates/project2/src/project2.rs index b0fde1c486..83608a5dfd 100644 --- a/crates/project2/src/project2.rs +++ b/crates/project2/src/project2.rs @@ -92,6 +92,8 @@ use util::{ pub use fs::*; pub use worktree::*; +const MAX_SERVER_REINSTALL_ATTEMPT_COUNT: u64 = 4; + pub trait Item { fn entry_id(&self, cx: &AppContext) -> Option; fn project_path(&self, cx: &AppContext) -> Option; @@ -2774,6 +2776,10 @@ impl Project { language: Arc, cx: &mut ModelContext, ) { + if adapter.reinstall_attempt_count.load(SeqCst) > MAX_SERVER_REINSTALL_ATTEMPT_COUNT { + return; + } + let key = (worktree_id, adapter.name.clone()); if self.language_server_ids.contains_key(&key) { return; @@ -2833,28 +2839,34 @@ impl Project { } Err(err) => { - log::error!("failed to start language server {:?}: {}", server_name, err); + log::error!("failed to start language server {server_name:?}: {err}"); log::error!("server stderr: {:?}", stderr_capture.lock().take()); - if let Some(this) = this.upgrade() { - if let Some(container_dir) = container_dir { - let installation_test_binary = adapter - .installation_test_binary(container_dir.to_path_buf()) - .await; + let this = this.upgrade()?; + let container_dir = container_dir?; - this.update(&mut cx, |_, cx| { - Self::check_errored_server( - language, - adapter, - server_id, - installation_test_binary, - cx, - ) - }) - .ok(); - } + let attempt_count = adapter.reinstall_attempt_count.fetch_add(1, SeqCst); + if attempt_count >= MAX_SERVER_REINSTALL_ATTEMPT_COUNT { + let max = MAX_SERVER_REINSTALL_ATTEMPT_COUNT; + log::error!("Hit {max} reinstallation attempts for {server_name:?}"); + return None; } + let installation_test_binary = adapter + .installation_test_binary(container_dir.to_path_buf()) + .await; + + this.update(&mut cx, |_, cx| { + Self::check_errored_server( + language, + adapter, + server_id, + installation_test_binary, + cx, + ) + }) + .ok(); + None } }