aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_lsp_server
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2019-01-11 13:58:01 +0000
committerAleksey Kladov <[email protected]>2019-01-11 14:08:49 +0000
commit4089db1e0d43ed22593468b9e88dde953849aeee (patch)
tree51dc4dde829fa997035cf068b668f3378c8f9f6a /crates/ra_lsp_server
parent0f4bc7589c40732fb78cb59525a6b4dcfb515567 (diff)
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.
Diffstat (limited to 'crates/ra_lsp_server')
-rw-r--r--crates/ra_lsp_server/src/main_loop.rs19
1 files changed, 15 insertions, 4 deletions
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 {
47 Notify(RawNotification), 47 Notify(RawNotification),
48} 48}
49 49
50const THREADPOOL_SIZE: usize = 8;
51
50pub fn main_loop( 52pub fn main_loop(
51 internal_mode: bool, 53 internal_mode: bool,
52 ws_root: PathBuf, 54 ws_root: PathBuf,
@@ -54,7 +56,7 @@ pub fn main_loop(
54 msg_receiver: &Receiver<RawMessage>, 56 msg_receiver: &Receiver<RawMessage>,
55 msg_sender: &Sender<RawMessage>, 57 msg_sender: &Sender<RawMessage>,
56) -> Result<()> { 58) -> Result<()> {
57 let pool = ThreadPool::new(8); 59 let pool = ThreadPool::new(THREADPOOL_SIZE);
58 let (task_sender, task_receiver) = unbounded::<Task>(); 60 let (task_sender, task_receiver) = unbounded::<Task>();
59 let (ws_worker, ws_watcher) = workspace_loader(); 61 let (ws_worker, ws_watcher) = workspace_loader();
60 62
@@ -164,6 +166,11 @@ fn main_loop_inner(
164 pending_requests: &mut FxHashSet<u64>, 166 pending_requests: &mut FxHashSet<u64>,
165 subs: &mut Subscriptions, 167 subs: &mut Subscriptions,
166) -> Result<()> { 168) -> Result<()> {
169 // We try not to index more than THREADPOOL_SIZE - 3 libraries at the same
170 // time to always have a thread ready to react to input.
171 let mut in_flight_libraries = 0;
172 let mut pending_libraries = Vec::new();
173
167 let (libdata_sender, libdata_receiver) = unbounded(); 174 let (libdata_sender, libdata_receiver) = unbounded();
168 loop { 175 loop {
169 log::trace!("selecting"); 176 log::trace!("selecting");
@@ -191,6 +198,7 @@ fn main_loop_inner(
191 Event::Lib(lib) => { 198 Event::Lib(lib) => {
192 feedback(internal_mode, "library loaded", msg_sender); 199 feedback(internal_mode, "library loaded", msg_sender);
193 state.add_lib(lib); 200 state.add_lib(lib);
201 in_flight_libraries -= 1;
194 } 202 }
195 Event::Msg(msg) => match msg { 203 Event::Msg(msg) => match msg {
196 RawMessage::Request(req) => { 204 RawMessage::Request(req) => {
@@ -219,8 +227,10 @@ fn main_loop_inner(
219 }, 227 },
220 }; 228 };
221 229
222 for lib in state.process_changes() { 230 pending_libraries.extend(state.process_changes());
223 let (root, files) = lib; 231 while in_flight_libraries < THREADPOOL_SIZE - 3 && !pending_libraries.is_empty() {
232 let (root, files) = pending_libraries.pop().unwrap();
233 in_flight_libraries += 1;
224 let sender = libdata_sender.clone(); 234 let sender = libdata_sender.clone();
225 pool.execute(move || { 235 pool.execute(move || {
226 let start = ::std::time::Instant::now(); 236 let start = ::std::time::Instant::now();
@@ -230,7 +240,8 @@ fn main_loop_inner(
230 sender.send(data).unwrap(); 240 sender.send(data).unwrap();
231 }); 241 });
232 } 242 }
233 if state.roots_to_scan == 0 { 243
244 if state.roots_to_scan == 0 && pending_libraries.is_empty() && in_flight_libraries == 0 {
234 feedback(internal_mode, "workspace loaded", msg_sender); 245 feedback(internal_mode, "workspace loaded", msg_sender);
235 } 246 }
236 247