From c6537c3280ba1c5df27c1ced9d4944a2acb02b6c Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Fri, 31 May 2019 20:50:16 +0300 Subject: add sync requests --- crates/ra_lsp_server/src/main_loop.rs | 95 +++++++++++++++++++++-------------- 1 file changed, 56 insertions(+), 39 deletions(-) (limited to 'crates/ra_lsp_server/src/main_loop.rs') diff --git a/crates/ra_lsp_server/src/main_loop.rs b/crates/ra_lsp_server/src/main_loop.rs index 8f41937dc..8a7c53d2c 100644 --- a/crates/ra_lsp_server/src/main_loop.rs +++ b/crates/ra_lsp_server/src/main_loop.rs @@ -2,7 +2,7 @@ mod handlers; mod subscriptions; pub(crate) mod pending_requests; -use std::{fmt, path::PathBuf, sync::Arc, time::Instant, any::TypeId}; +use std::{fmt, path::PathBuf, sync::Arc, time::Instant}; use crossbeam_channel::{select, unbounded, Receiver, RecvError, Sender}; use failure::{bail, format_err}; @@ -219,22 +219,15 @@ fn main_loop_inner( Some(req) => req, None => return Ok(()), }; - match req.cast::() { - Ok((id, ())) => { - state.collect_garbage(); - let resp = RawResponse::ok::(id, &()); - msg_sender.send(resp.into()).unwrap() - } - Err(req) => on_request( - state, - pending_requests, - pool, - &task_sender, - msg_sender, - loop_start, - req, - )?, - } + on_request( + state, + pending_requests, + pool, + &task_sender, + msg_sender, + loop_start, + req, + )? } RawMessage::Notification(not) => { on_notification(msg_sender, state, pending_requests, subs, not)?; @@ -322,6 +315,7 @@ fn on_request( request_received, }; pool_dispatcher + .on_sync::(|state, ()| Ok(state.collect_garbage()))? .on::(handlers::handle_analyzer_status)? .on::(handlers::handle_syntax_tree)? .on::(handlers::handle_extend_selection)? @@ -434,37 +428,39 @@ struct PoolDispatcher<'a> { } impl<'a> PoolDispatcher<'a> { - fn on(&mut self, f: fn(ServerWorld, R::Params) -> Result) -> Result<&mut Self> + fn on_sync( + &mut self, + f: fn(&mut ServerWorldState, R::Params) -> Result, + ) -> Result<&mut Self> where R: req::Request + 'static, R::Params: DeserializeOwned + Send + 'static, R::Result: Serialize + 'static, { - let req = match self.req.take() { - None => return Ok(self), - Some(req) => req, - }; - let (id, params) = match req.cast::() { - Ok(it) => it, - Err(req) => { - self.req = Some(req); + let (id, params) = match self.parse::() { + Some(it) => it, + None => { return Ok(self); } }; - self.pending_requests.start(PendingRequest { - id, - method: R::METHOD.to_string(), - received: self.request_received, - }); + let result = f(self.world, params); + let task = result_to_task::(id, result); + on_task(task, self.msg_sender, self.pending_requests, self.world); + Ok(self) + } - // Real time requests block user typing, so we should react quickly to them. - // Currently this means that we try to cancel background jobs if we don't have - // a spare thread. - let is_real_time = TypeId::of::() == TypeId::of::() - || TypeId::of::() == TypeId::of::(); - if self.pool.queued_count() > 0 && is_real_time { - self.world.cancel_requests(); - } + fn on(&mut self, f: fn(ServerWorld, R::Params) -> Result) -> Result<&mut Self> + where + R: req::Request + 'static, + R::Params: DeserializeOwned + Send + 'static, + R::Result: Serialize + 'static, + { + let (id, params) = match self.parse::() { + Some(it) => it, + None => { + return Ok(self); + } + }; self.pool.execute({ let world = self.world.snapshot(); @@ -479,6 +475,27 @@ impl<'a> PoolDispatcher<'a> { Ok(self) } + fn parse(&mut self) -> Option<(u64, R::Params)> + where + R: req::Request + 'static, + R::Params: DeserializeOwned + Send + 'static, + { + let req = self.req.take()?; + let (id, params) = match req.cast::() { + Ok(it) => it, + Err(req) => { + self.req = Some(req); + return None; + } + }; + self.pending_requests.start(PendingRequest { + id, + method: R::METHOD.to_string(), + received: self.request_received, + }); + Some((id, params)) + } + fn finish(&mut self) { match self.req.take() { None => (), -- cgit v1.2.3