@@ -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<String>,
pub language_ids: HashMap<String, String>,
pub adapter: Arc<dyn LspAdapter>,
+ 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),
})
}
@@ -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<ProjectEntryId>;
fn project_path(&self, cx: &AppContext) -> Option<ProjectPath>;
@@ -2774,6 +2776,10 @@ impl Project {
language: Arc<Language>,
cx: &mut ModelContext<Self>,
) {
+ 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;
-
- this.update(&mut cx, |_, cx| {
- Self::check_errored_server(
- language,
- adapter,
- server_id,
- installation_test_binary,
- cx,
- )
- })
- .ok();
- }
+ let this = this.upgrade()?;
+ let container_dir = container_dir?;
+
+ 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
}
}