From e1bda6aeda084e6e913b80959dbf6ce6260d1db2 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Fri, 31 May 2019 20:14:54 +0300 Subject: move completed requests to a separate file --- crates/ra_lsp_server/src/main_loop/handlers.rs | 8 +-- .../src/main_loop/pending_requests.rs | 72 ++++++++++++++++++++++ .../ra_lsp_server/src/main_loop/subscriptions.rs | 12 ++-- 3 files changed, 81 insertions(+), 11 deletions(-) create mode 100644 crates/ra_lsp_server/src/main_loop/pending_requests.rs (limited to 'crates/ra_lsp_server/src/main_loop') diff --git a/crates/ra_lsp_server/src/main_loop/handlers.rs b/crates/ra_lsp_server/src/main_loop/handlers.rs index 0ebfd641d..8cfb6a192 100644 --- a/crates/ra_lsp_server/src/main_loop/handlers.rs +++ b/crates/ra_lsp_server/src/main_loop/handlers.rs @@ -31,10 +31,10 @@ use crate::{ pub fn handle_analyzer_status(world: ServerWorld, _: ()) -> Result { let mut buf = world.status(); writeln!(buf, "\n\nrequests:").unwrap(); - let requests = world.latest_completed_requests.read(); - for (idx, r) in requests.iter().enumerate() { - let current = if idx == world.request_idx { "*" } else { " " }; - writeln!(buf, "{:4}{}{:<36}{}ms", r.id, current, r.method, r.duration.as_millis()).unwrap(); + let requests = world.latest_requests.read(); + for (is_last, r) in requests.iter() { + let mark = if is_last { "*" } else { " " }; + writeln!(buf, "{}{:4} {:<36}{}ms", mark, r.id, r.method, r.duration.as_millis()).unwrap(); } Ok(buf) } diff --git a/crates/ra_lsp_server/src/main_loop/pending_requests.rs b/crates/ra_lsp_server/src/main_loop/pending_requests.rs new file mode 100644 index 000000000..741770e45 --- /dev/null +++ b/crates/ra_lsp_server/src/main_loop/pending_requests.rs @@ -0,0 +1,72 @@ +use std::time::{Duration, Instant}; + +use rustc_hash::FxHashMap; + +#[derive(Debug)] +pub struct CompletedRequest { + pub id: u64, + pub method: String, + pub duration: Duration, +} + +#[derive(Debug)] +pub(crate) struct PendingRequest { + pub(crate) id: u64, + pub(crate) method: String, + pub(crate) received: Instant, +} + +impl From for CompletedRequest { + fn from(pending: PendingRequest) -> CompletedRequest { + CompletedRequest { + id: pending.id, + method: pending.method, + duration: pending.received.elapsed(), + } + } +} + +#[derive(Debug, Default)] +pub(crate) struct PendingRequests { + map: FxHashMap, +} + +impl PendingRequests { + pub(crate) fn start(&mut self, request: PendingRequest) { + let id = request.id; + let prev = self.map.insert(id, request); + assert!(prev.is_none(), "duplicate request with id {}", id); + } + pub(crate) fn cancel(&mut self, id: u64) -> bool { + self.map.remove(&id).is_some() + } + pub(crate) fn finish(&mut self, id: u64) -> Option { + self.map.remove(&id).map(CompletedRequest::from) + } +} + +const N_COMPLETED_REQUESTS: usize = 10; + +#[derive(Debug, Default)] +pub struct LatestRequests { + // hand-rolling VecDeque here to print things in a nicer way + buf: [Option; N_COMPLETED_REQUESTS], + idx: usize, +} + +impl LatestRequests { + pub(crate) fn record(&mut self, request: CompletedRequest) { + // special case: don't track status request itself + if request.method == "rust-analyzer/analyzerStatus" { + return; + } + let idx = self.idx; + self.buf[idx] = Some(request); + self.idx = (idx + 1) % N_COMPLETED_REQUESTS; + } + + pub(crate) fn iter(&self) -> impl Iterator { + let idx = self.idx; + self.buf.iter().enumerate().filter_map(move |(i, req)| Some((i == idx, req.as_ref()?))) + } +} diff --git a/crates/ra_lsp_server/src/main_loop/subscriptions.rs b/crates/ra_lsp_server/src/main_loop/subscriptions.rs index 11bd952d9..470bc1205 100644 --- a/crates/ra_lsp_server/src/main_loop/subscriptions.rs +++ b/crates/ra_lsp_server/src/main_loop/subscriptions.rs @@ -1,21 +1,19 @@ use ra_ide_api::FileId; use rustc_hash::FxHashSet; -pub struct Subscriptions { +#[derive(Default)] +pub(crate) struct Subscriptions { subs: FxHashSet, } impl Subscriptions { - pub fn new() -> Subscriptions { - Subscriptions { subs: FxHashSet::default() } - } - pub fn add_sub(&mut self, file_id: FileId) { + pub(crate) fn add_sub(&mut self, file_id: FileId) { self.subs.insert(file_id); } - pub fn remove_sub(&mut self, file_id: FileId) { + pub(crate) fn remove_sub(&mut self, file_id: FileId) { self.subs.remove(&file_id); } - pub fn subscriptions(&self) -> Vec { + pub(crate) fn subscriptions(&self) -> Vec { self.subs.iter().cloned().collect() } } -- cgit v1.2.3