Revert "Debounce language server file system events (#30773)" (#31008)

Let's keep https://github.com/zed-industries/zed/pull/30773 and its
complexity out of Zed sources if we can:
https://github.com/rust-lang/rust-analyzer/pull/19814 seems to do a
similar thing and might have fixed the root cause.

If not, we can always reapply this later after ensuring.

Release Notes:

- N/A
This commit is contained in:
Kirill Bulatov 2025-05-20 15:05:21 +03:00 committed by GitHub
parent a1be61949d
commit 944a0df436
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 20 additions and 63 deletions

View file

@ -104,7 +104,6 @@ pub use worktree::{
const SERVER_LAUNCHING_BEFORE_SHUTDOWN_TIMEOUT: Duration = Duration::from_secs(5); const SERVER_LAUNCHING_BEFORE_SHUTDOWN_TIMEOUT: Duration = Duration::from_secs(5);
pub const SERVER_PROGRESS_THROTTLE_TIMEOUT: Duration = Duration::from_millis(100); pub const SERVER_PROGRESS_THROTTLE_TIMEOUT: Duration = Duration::from_millis(100);
pub const FS_WATCH_DEBOUNCE_TIMEOUT: Duration = Duration::from_millis(500);
#[derive(Debug, Clone, Copy, PartialEq, Eq)] #[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum FormatTrigger { pub enum FormatTrigger {
@ -9221,9 +9220,7 @@ impl LspStore {
return; return;
} }
let Some(local) = self.as_local_mut() else { let Some(local) = self.as_local() else { return };
return;
};
local.prettier_store.update(cx, |prettier_store, cx| { local.prettier_store.update(cx, |prettier_store, cx| {
prettier_store.update_prettier_settings(&worktree_handle, changes, cx) prettier_store.update_prettier_settings(&worktree_handle, changes, cx)
@ -9243,53 +9240,22 @@ impl LspStore {
language_server_ids.dedup(); language_server_ids.dedup();
let abs_path = worktree_handle.read(cx).abs_path(); let abs_path = worktree_handle.read(cx).abs_path();
for server_id in &language_server_ids { for server_id in &language_server_ids {
let Some(watch) = local.language_server_watched_paths.get_mut(&server_id) else { if let Some(LanguageServerState::Running { server, .. }) =
continue; local.language_servers.get(server_id)
}; {
let Some(watched_paths) = watch.worktree_paths.get(&worktree_id) else { if let Some(watched_paths) = local
continue; .language_server_watched_paths
}; .get(server_id)
.and_then(|paths| paths.worktree_paths.get(&worktree_id))
for (path, _, change) in changes { {
if !watched_paths.is_match(path) {
continue;
}
let file_abs_path = abs_path.join(path);
watch.pending_events.insert(file_abs_path, *change);
}
if watch.pending_events.is_empty() {
continue;
}
let server_id = *server_id;
watch.flush_timer_task = Some(cx.spawn(async move |this, cx| {
cx.background_executor()
.timer(FS_WATCH_DEBOUNCE_TIMEOUT)
.await;
this.update(cx, |this, _cx| {
let Some(this) = this.as_local_mut() else {
return;
};
let Some(LanguageServerState::Running { server, .. }) =
this.language_servers.get(&server_id)
else {
return;
};
let Some(watch) = this.language_server_watched_paths.get_mut(&server_id) else {
return;
};
let params = lsp::DidChangeWatchedFilesParams { let params = lsp::DidChangeWatchedFilesParams {
changes: watch changes: changes
.pending_events .iter()
.drain() .filter_map(|(path, _, change)| {
.filter_map(|(path, change)| { if !watched_paths.is_match(path) {
return None;
}
let typ = match change { let typ = match change {
PathChange::Loaded => return None, PathChange::Loaded => return None,
PathChange::Added => lsp::FileChangeType::CREATED, PathChange::Added => lsp::FileChangeType::CREATED,
@ -9298,21 +9264,19 @@ impl LspStore {
PathChange::AddedOrUpdated => lsp::FileChangeType::CHANGED, PathChange::AddedOrUpdated => lsp::FileChangeType::CHANGED,
}; };
Some(lsp::FileEvent { Some(lsp::FileEvent {
uri: lsp::Url::from_file_path(&path).unwrap(), uri: lsp::Url::from_file_path(abs_path.join(path)).unwrap(),
typ, typ,
}) })
}) })
.collect(), .collect(),
}; };
if !params.changes.is_empty() { if !params.changes.is_empty() {
server server
.notify::<lsp::notification::DidChangeWatchedFiles>(&params) .notify::<lsp::notification::DidChangeWatchedFiles>(&params)
.ok(); .ok();
} }
}) }
.log_err(); }
}));
} }
} }
@ -9757,8 +9721,6 @@ impl RenameActionPredicate {
#[derive(Default)] #[derive(Default)]
struct LanguageServerWatchedPaths { struct LanguageServerWatchedPaths {
worktree_paths: HashMap<WorktreeId, GlobSet>, worktree_paths: HashMap<WorktreeId, GlobSet>,
pending_events: HashMap<PathBuf, PathChange>,
flush_timer_task: Option<Task<()>>,
abs_paths: HashMap<Arc<Path>, (GlobSet, Task<()>)>, abs_paths: HashMap<Arc<Path>, (GlobSet, Task<()>)>,
} }
@ -9837,8 +9799,6 @@ impl LanguageServerWatchedPathsBuilder {
.collect(); .collect();
LanguageServerWatchedPaths { LanguageServerWatchedPaths {
worktree_paths: self.worktree_paths, worktree_paths: self.worktree_paths,
pending_events: HashMap::default(),
flush_timer_task: None,
abs_paths, abs_paths,
} }
} }

View file

@ -1,8 +1,8 @@
#![allow(clippy::format_collect)] #![allow(clippy::format_collect)]
use crate::{ use crate::{
Event, git_store::StatusEntry, lsp_store::FS_WATCH_DEBOUNCE_TIMEOUT, Event, git_store::StatusEntry, task_inventory::TaskContexts, task_store::TaskSettingsLocation,
task_inventory::TaskContexts, task_store::TaskSettingsLocation, *, *,
}; };
use buffer_diff::{ use buffer_diff::{
BufferDiffEvent, CALCULATE_DIFF_TASK, DiffHunkSecondaryStatus, DiffHunkStatus, BufferDiffEvent, CALCULATE_DIFF_TASK, DiffHunkSecondaryStatus, DiffHunkStatus,
@ -1190,9 +1190,6 @@ async fn test_reporting_fs_changes_to_language_servers(cx: &mut gpui::TestAppCon
// The language server receives events for the FS mutations that match its watch patterns. // The language server receives events for the FS mutations that match its watch patterns.
cx.executor().run_until_parked(); cx.executor().run_until_parked();
cx.executor().advance_clock(FS_WATCH_DEBOUNCE_TIMEOUT);
cx.executor().run_until_parked();
assert_eq!( assert_eq!(
&*file_changes.lock(), &*file_changes.lock(),
&[ &[