From 4089db1e0d43ed22593468b9e88dde953849aeee Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Fri, 11 Jan 2019 16:58:01 +0300 Subject: prioritize event handing over indexing If we index gazillion libraries simultaneously, we fill the threadpool and so the main loop fails to turn, although there isn't really any significant blocking inside the loop itself. --- crates/ra_lsp_server/src/main_loop.rs | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) (limited to 'crates') diff --git a/crates/ra_lsp_server/src/main_loop.rs b/crates/ra_lsp_server/src/main_loop.rs index 7fc0b8f50..c43637351 100644 --- a/crates/ra_lsp_server/src/main_loop.rs +++ b/crates/ra_lsp_server/src/main_loop.rs @@ -47,6 +47,8 @@ enum Task { Notify(RawNotification), } +const THREADPOOL_SIZE: usize = 8; + pub fn main_loop( internal_mode: bool, ws_root: PathBuf, @@ -54,7 +56,7 @@ pub fn main_loop( msg_receiver: &Receiver, msg_sender: &Sender, ) -> Result<()> { - let pool = ThreadPool::new(8); + let pool = ThreadPool::new(THREADPOOL_SIZE); let (task_sender, task_receiver) = unbounded::(); let (ws_worker, ws_watcher) = workspace_loader(); @@ -164,6 +166,11 @@ fn main_loop_inner( pending_requests: &mut FxHashSet, subs: &mut Subscriptions, ) -> Result<()> { + // We try not to index more than THREADPOOL_SIZE - 3 libraries at the same + // time to always have a thread ready to react to input. + let mut in_flight_libraries = 0; + let mut pending_libraries = Vec::new(); + let (libdata_sender, libdata_receiver) = unbounded(); loop { log::trace!("selecting"); @@ -191,6 +198,7 @@ fn main_loop_inner( Event::Lib(lib) => { feedback(internal_mode, "library loaded", msg_sender); state.add_lib(lib); + in_flight_libraries -= 1; } Event::Msg(msg) => match msg { RawMessage::Request(req) => { @@ -219,8 +227,10 @@ fn main_loop_inner( }, }; - for lib in state.process_changes() { - let (root, files) = lib; + pending_libraries.extend(state.process_changes()); + while in_flight_libraries < THREADPOOL_SIZE - 3 && !pending_libraries.is_empty() { + let (root, files) = pending_libraries.pop().unwrap(); + in_flight_libraries += 1; let sender = libdata_sender.clone(); pool.execute(move || { let start = ::std::time::Instant::now(); @@ -230,7 +240,8 @@ fn main_loop_inner( sender.send(data).unwrap(); }); } - if state.roots_to_scan == 0 { + + if state.roots_to_scan == 0 && pending_libraries.is_empty() && in_flight_libraries == 0 { feedback(internal_mode, "workspace loaded", msg_sender); } -- cgit v1.2.3