Wait with change processing until the vfs is done

This commit is contained in:
Lukas Wirth 2024-08-02 17:09:25 +02:00
parent 8286847bee
commit c6ae9cde99
5 changed files with 34 additions and 30 deletions

View file

@ -33,7 +33,7 @@ use crate::{
lsp_ext,
main_loop::Task,
mem_docs::MemDocs,
op_queue::OpQueue,
op_queue::{Cause, OpQueue},
reload,
target_spec::{CargoTargetSpec, ProjectJsonTargetSpec, TargetSpec},
task_pool::{TaskPool, TaskQueue},
@ -108,8 +108,8 @@ pub(crate) struct GlobalState {
pub(crate) vfs: Arc<RwLock<(vfs::Vfs, IntMap<FileId, LineEndings>)>>,
pub(crate) vfs_config_version: u32,
pub(crate) vfs_progress_config_version: u32,
pub(crate) vfs_progress_n_total: usize,
pub(crate) vfs_progress_n_done: usize,
pub(crate) vfs_done: bool,
pub(crate) wants_to_switch: Option<Cause>,
/// `workspaces` field stores the data we actually use, while the `OpQueue`
/// stores the result of the last fetch.
@ -252,8 +252,8 @@ impl GlobalState {
vfs: Arc::new(RwLock::new((vfs::Vfs::default(), IntMap::default()))),
vfs_config_version: 0,
vfs_progress_config_version: 0,
vfs_progress_n_total: 0,
vfs_progress_n_done: 0,
vfs_done: true,
wants_to_switch: None,
workspaces: Arc::from(Vec::new()),
crate_graph_file_dependencies: FxHashSet::default(),

View file

@ -375,9 +375,14 @@ impl GlobalState {
}
}
let event_handling_duration = loop_start.elapsed();
let state_changed = self.process_changes();
let memdocs_added_or_removed = self.mem_docs.take_changes();
let (state_changed, memdocs_added_or_removed) = if self.vfs_done {
if let Some(cause) = self.wants_to_switch.take() {
self.switch_workspaces(cause);
}
(self.process_changes(), self.mem_docs.take_changes())
} else {
(false, false)
};
if self.is_quiescent() {
let became_quiescent = !was_quiescent;
@ -672,7 +677,7 @@ impl GlobalState {
if let Err(e) = self.fetch_workspace_error() {
error!("FetchWorkspaceError:\n{e}");
}
self.switch_workspaces("fetched workspace".to_owned());
self.wants_to_switch = Some("fetched workspace".to_owned());
(Progress::End, None)
}
};
@ -718,8 +723,9 @@ impl GlobalState {
error!("FetchBuildDataError:\n{e}");
}
self.switch_workspaces("fetched build data".to_owned());
if self.wants_to_switch.is_none() {
self.wants_to_switch = Some("fetched build data".to_owned());
}
(Some(Progress::End), None)
}
};
@ -779,8 +785,7 @@ impl GlobalState {
};
self.vfs_progress_config_version = config_version;
self.vfs_progress_n_total = n_total;
self.vfs_progress_n_done = n_done;
self.vfs_done = state == Progress::End;
let mut message = format!("{n_done}/{n_total}");
if let Some(dir) = dir {

View file

@ -62,13 +62,13 @@ pub(crate) enum ProcMacroProgress {
impl GlobalState {
pub(crate) fn is_quiescent(&self) -> bool {
!(self.last_reported_status.is_none()
|| self.fetch_workspaces_queue.op_in_progress()
|| self.fetch_build_data_queue.op_in_progress()
|| self.fetch_proc_macros_queue.op_in_progress()
|| self.discover_workspace_queue.op_in_progress()
|| self.vfs_progress_config_version < self.vfs_config_version
|| self.vfs_progress_n_done < self.vfs_progress_n_total)
self.vfs_done
&& self.last_reported_status.is_some()
&& !self.fetch_workspaces_queue.op_in_progress()
&& !self.fetch_build_data_queue.op_in_progress()
&& !self.fetch_proc_macros_queue.op_in_progress()
&& !self.discover_workspace_queue.op_in_progress()
&& self.vfs_progress_config_version >= self.vfs_config_version
}
pub(crate) fn update_configuration(&mut self, config: Config) {
@ -102,15 +102,13 @@ impl GlobalState {
}
pub(crate) fn current_status(&self) -> lsp_ext::ServerStatusParams {
let mut status = lsp_ext::ServerStatusParams {
health: lsp_ext::Health::Ok,
quiescent: self.is_quiescent(),
message: None,
};
let quiescent = self.is_quiescent();
let mut status =
lsp_ext::ServerStatusParams { health: lsp_ext::Health::Ok, quiescent, message: None };
let mut message = String::new();
if !self.config.cargo_autoreload(None)
&& self.is_quiescent()
&& quiescent
&& self.fetch_workspaces_queue.op_requested()
&& self.config.discover_workspace_config().is_none()
{
@ -242,7 +240,7 @@ impl GlobalState {
let discover_command = self.config.discover_workspace_config().cloned();
let is_quiescent = !(self.discover_workspace_queue.op_in_progress()
|| self.vfs_progress_config_version < self.vfs_config_version
|| self.vfs_progress_n_done < self.vfs_progress_n_total);
|| !self.vfs_done);
move |sender| {
let progress = {

View file

@ -61,6 +61,7 @@ type NotifyEvent = notify::Result<notify::Event>;
struct NotifyActor {
sender: loader::Sender,
// FIXME: Consider hashset
watched_entries: Vec<loader::Entry>,
// Drop order is significant.
watcher: Option<(RecommendedWatcher, Receiver<NotifyEvent>)>,

View file

@ -201,8 +201,8 @@ impl Vfs {
pub fn set_file_contents(&mut self, path: VfsPath, contents: Option<Vec<u8>>) -> bool {
let _p = span!(Level::INFO, "Vfs::set_file_contents").entered();
let file_id = self.alloc_file_id(path);
let state = self.get(file_id);
let change_kind = match (state, contents) {
let state: FileState = self.get(file_id);
let change = match (state, contents) {
(FileState::Deleted, None) => return false,
(FileState::Deleted, Some(v)) => {
let hash = hash_once::<FxHasher>(&*v);
@ -225,7 +225,7 @@ impl Vfs {
};
};
let changed_file = ChangedFile { file_id, change: change_kind };
let changed_file = ChangedFile { file_id, change };
match self.changes.entry(file_id) {
// two changes to the same file in one cycle, merge them appropriately
Entry::Occupied(mut o) => {