aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_lsp_server/src/main_loop/pending_requests.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_lsp_server/src/main_loop/pending_requests.rs')
-rw-r--r--crates/ra_lsp_server/src/main_loop/pending_requests.rs72
1 files changed, 72 insertions, 0 deletions
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 @@
1use std::time::{Duration, Instant};
2
3use rustc_hash::FxHashMap;
4
5#[derive(Debug)]
6pub struct CompletedRequest {
7 pub id: u64,
8 pub method: String,
9 pub duration: Duration,
10}
11
12#[derive(Debug)]
13pub(crate) struct PendingRequest {
14 pub(crate) id: u64,
15 pub(crate) method: String,
16 pub(crate) received: Instant,
17}
18
19impl From<PendingRequest> for CompletedRequest {
20 fn from(pending: PendingRequest) -> CompletedRequest {
21 CompletedRequest {
22 id: pending.id,
23 method: pending.method,
24 duration: pending.received.elapsed(),
25 }
26 }
27}
28
29#[derive(Debug, Default)]
30pub(crate) struct PendingRequests {
31 map: FxHashMap<u64, PendingRequest>,
32}
33
34impl PendingRequests {
35 pub(crate) fn start(&mut self, request: PendingRequest) {
36 let id = request.id;
37 let prev = self.map.insert(id, request);
38 assert!(prev.is_none(), "duplicate request with id {}", id);
39 }
40 pub(crate) fn cancel(&mut self, id: u64) -> bool {
41 self.map.remove(&id).is_some()
42 }
43 pub(crate) fn finish(&mut self, id: u64) -> Option<CompletedRequest> {
44 self.map.remove(&id).map(CompletedRequest::from)
45 }
46}
47
48const N_COMPLETED_REQUESTS: usize = 10;
49
50#[derive(Debug, Default)]
51pub struct LatestRequests {
52 // hand-rolling VecDeque here to print things in a nicer way
53 buf: [Option<CompletedRequest>; N_COMPLETED_REQUESTS],
54 idx: usize,
55}
56
57impl LatestRequests {
58 pub(crate) fn record(&mut self, request: CompletedRequest) {
59 // special case: don't track status request itself
60 if request.method == "rust-analyzer/analyzerStatus" {
61 return;
62 }
63 let idx = self.idx;
64 self.buf[idx] = Some(request);
65 self.idx = (idx + 1) % N_COMPLETED_REQUESTS;
66 }
67
68 pub(crate) fn iter(&self) -> impl Iterator<Item = (bool, &CompletedRequest)> {
69 let idx = self.idx;
70 self.buf.iter().enumerate().filter_map(move |(i, req)| Some((i == idx, req.as_ref()?)))
71 }
72}