about summary refs log tree commit diff
diff options
context:
space:
mode:
authorVeetaha <veetaha2@gmail.com>2020-08-08 21:53:38 +0300
committerVeetaha <veetaha2@gmail.com>2020-08-08 21:53:38 +0300
commite43811c1645f78818d5d7fe0054b54a462145847 (patch)
tree43c7e67da3e783af3f06033478d306a2cfc99490
parenta69f19a6a5899bdfb6fc498371650bf54263deff (diff)
downloadrust-e43811c1645f78818d5d7fe0054b54a462145847.tar.gz
rust-e43811c1645f78818d5d7fe0054b54a462145847.zip
Fix no inlay hints / unresolved tokens until manual edit
No we return ContentModified during the workspace loading. This signifies the language
client to retry the operation (i.e. the client will
continue polling the server while it returns ContentModified).
I believe that there might be cases of overly big projects where the backoff
logic we have setup in `sendRequestWithRetry` (which we use for inlay hints)
might bail too early (currently the largest retry standby time is 10 seconds).
However, I've tried on one of my project with 500+ dependencies and it is still enough.
-rw-r--r--crates/rust-analyzer/src/main_loop.rs10
-rw-r--r--editors/code/src/util.ts6
2 files changed, 13 insertions, 3 deletions
diff --git a/crates/rust-analyzer/src/main_loop.rs b/crates/rust-analyzer/src/main_loop.rs
index ceddb2b0563..d69f7941d86 100644
--- a/crates/rust-analyzer/src/main_loop.rs
+++ b/crates/rust-analyzer/src/main_loop.rs
@@ -337,6 +337,16 @@ impl GlobalState {
     fn on_request(&mut self, request_received: Instant, req: Request) -> Result<()> {
         self.register_request(&req, request_received);
 
+        if self.status == Status::Loading {
+            self.respond(lsp_server::Response::new_err(
+                req.id,
+                // FIXME: i32 should impl From<ErrorCode> (from() guarantees lossless conversion)
+                lsp_server::ErrorCode::ContentModified as i32,
+                "Rust Analyzer is still loading...".to_owned(),
+            ));
+            return Ok(());
+        }
+
         RequestDispatcher { req: Some(req), global_state: self }
             .on_sync::<lsp_ext::ReloadWorkspace>(|s, ()| Ok(s.fetch_workspaces()))?
             .on_sync::<lsp_ext::JoinLines>(|s, p| handlers::handle_join_lines(s.snapshot(), p))?
diff --git a/editors/code/src/util.ts b/editors/code/src/util.ts
index 970fedb3787..49d2d1c6fbe 100644
--- a/editors/code/src/util.ts
+++ b/editors/code/src/util.ts
@@ -64,7 +64,8 @@ export async function sendRequestWithRetry<TParam, TRet>(
     param: TParam,
     token?: vscode.CancellationToken,
 ): Promise<TRet> {
-    for (const delay of [2, 4, 6, 8, 10, null]) {
+    // The sequence is `10 * (2 ** (2 * n))` where n is 1, 2, 3...
+    for (const delay of [40, 160, 640, 2560, 10240, null]) {
         try {
             return await (token
                 ? client.sendRequest(reqType, param, token)
@@ -84,8 +85,7 @@ export async function sendRequestWithRetry<TParam, TRet>(
                 log.warn("LSP request failed", { method: reqType.method, param, error });
                 throw error;
             }
-
-            await sleep(10 * (1 << delay));
+            await sleep(delay);
         }
     }
     throw 'unreachable';