Skip to content

Commit

Permalink
Auto merge of rust-lang#17771 - Veykril:parallel-vfs-config, r=Veykril
Browse files Browse the repository at this point in the history
internal: Load VFS config changes in parallel

Simple attempt to make some progress f or rust-lang/rust-analyzer#17373
No clue if those atomic orderings are right, though I don't think they are really too relevant either.

A more complete fix would probably need to replace our `ProjectFolders` handling a bit.
  • Loading branch information
bors committed Aug 5, 2024
2 parents 81cbc78 + 314f301 commit 7dd258a
Show file tree
Hide file tree
Showing 10 changed files with 183 additions and 113 deletions.
2 changes: 2 additions & 0 deletions src/tools/rust-analyzer/Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2349,6 +2349,8 @@ dependencies = [
"crossbeam-channel",
"notify",
"paths",
"rayon",
"rustc-hash",
"stdx",
"tracing",
"vfs",
Expand Down
10 changes: 7 additions & 3 deletions src/tools/rust-analyzer/crates/load-cargo/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,11 @@ use project_model::{
CargoConfig, PackageRoot, ProjectManifest, ProjectWorkspace, ProjectWorkspaceKind,
};
use span::Span;
use vfs::{file_set::FileSetConfig, loader::Handle, AbsPath, AbsPathBuf, VfsPath};
use vfs::{
file_set::FileSetConfig,
loader::{Handle, LoadingProgress},
AbsPath, AbsPathBuf, VfsPath,
};

pub struct LoadCargoConfig {
pub load_out_dirs_from_check: bool,
Expand Down Expand Up @@ -409,8 +413,8 @@ fn load_crate_graph(
// wait until Vfs has loaded all roots
for task in receiver {
match task {
vfs::loader::Message::Progress { n_done, n_total, .. } => {
if n_done == Some(n_total) {
vfs::loader::Message::Progress { n_done, .. } => {
if n_done == LoadingProgress::Finished {
break;
}
}
Expand Down
10 changes: 5 additions & 5 deletions src/tools/rust-analyzer/crates/rust-analyzer/src/global_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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},
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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(),
Expand Down
32 changes: 18 additions & 14 deletions src/tools/rust-analyzer/crates/rust-analyzer/src/main_loop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use lsp_server::{Connection, Notification, Request};
use lsp_types::{notification::Notification as _, TextDocumentIdentifier};
use stdx::thread::ThreadIntent;
use tracing::{error, span, Level};
use vfs::{AbsPathBuf, FileId};
use vfs::{loader::LoadingProgress, AbsPathBuf, FileId};

use crate::{
config::Config,
Expand Down Expand Up @@ -381,9 +381,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;
Expand Down Expand Up @@ -691,7 +696,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)
}
};
Expand Down Expand Up @@ -737,8 +742,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)
}
};
Expand Down Expand Up @@ -791,16 +797,14 @@ impl GlobalState {
let _p = tracing::info_span!("GlobalState::handle_vfs_mgs/progress").entered();
always!(config_version <= self.vfs_config_version);

let state = match n_done {
None => Progress::Begin,
Some(done) if done == n_total => Progress::End,
Some(_) => Progress::Report,
let (n_done, state) = match n_done {
LoadingProgress::Started => (0, Progress::Begin),
LoadingProgress::Progress(n_done) => (n_done.min(n_total), Progress::Report),
LoadingProgress::Finished => (n_total, Progress::End),
};
let n_done = n_done.unwrap_or_default();

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 {
Expand Down
26 changes: 12 additions & 14 deletions src/tools/rust-analyzer/crates/rust-analyzer/src/reload.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -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()
{
Expand Down Expand Up @@ -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 = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -909,7 +909,7 @@ version = \"0.0.0\"

fn out_dirs_check_impl(root_contains_symlink: bool) {
if skip_slow_tests() {
// return;
return;
}

let mut server = Project::with_fixture(
Expand Down
4 changes: 3 additions & 1 deletion src/tools/rust-analyzer/crates/vfs-notify/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,12 @@ tracing.workspace = true
walkdir = "2.3.2"
crossbeam-channel = "0.5.5"
notify = "6.1.1"
rayon = "1.10.0"

stdx.workspace = true
vfs.workspace = true
paths.workspace = true
rustc-hash.workspace = true

[lints]
workspace = true
workspace = true
Loading

0 comments on commit 7dd258a

Please sign in to comment.