Skip to content

Commit b1cb4ac

Browse files
bors[bot]Veetaha
andauthored
Merge #5693
5693: Fix no inlay hints / unresolved tokens until manual edit to refresh r=jonas-schievink a=Veetaha Fixes #5349 Now 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. Here are the examples before/after the change (the gifs are quite lengthy because they show testing rather large cargo workspace). <details> <summary>Before</summary> Here you can see that the client receives empty array of inlay hints and does nothing more. Same applies to semantic tokens. The client receives unresolved tokens and does nothing more. The user needs to do a manual edit to refresh the editor. ![prev-demo](https://user-images.githubusercontent.com/36276403/89717721-e4471280-d9c1-11ea-89ce-7dc3e83d9768.gif) </details> <details> <summary>After</summary> Here the server returns ContentModified, so the client periodically retries the requests and eventually receives the wellformed response. ![new-demo](https://user-images.githubusercontent.com/36276403/89717725-eb6e2080-d9c1-11ea-84c9-796bb2b22cec.gif) </details> Co-authored-by: Veetaha <[email protected]>
2 parents 9995e79 + dbe7ede commit b1cb4ac

File tree

2 files changed

+13
-3
lines changed

2 files changed

+13
-3
lines changed

crates/rust-analyzer/src/main_loop.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -337,6 +337,16 @@ impl GlobalState {
337337
fn on_request(&mut self, request_received: Instant, req: Request) -> Result<()> {
338338
self.register_request(&req, request_received);
339339

340+
if self.status == Status::Loading && req.method != "shutdown" {
341+
self.respond(lsp_server::Response::new_err(
342+
req.id,
343+
// FIXME: i32 should impl From<ErrorCode> (from() guarantees lossless conversion)
344+
lsp_server::ErrorCode::ContentModified as i32,
345+
"Rust Analyzer is still loading...".to_owned(),
346+
));
347+
return Ok(());
348+
}
349+
340350
RequestDispatcher { req: Some(req), global_state: self }
341351
.on_sync::<lsp_ext::ReloadWorkspace>(|s, ()| Ok(s.fetch_workspaces()))?
342352
.on_sync::<lsp_ext::JoinLines>(|s, p| handlers::handle_join_lines(s.snapshot(), p))?

editors/code/src/util.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,8 @@ export async function sendRequestWithRetry<TParam, TRet>(
6464
param: TParam,
6565
token?: vscode.CancellationToken,
6666
): Promise<TRet> {
67-
for (const delay of [2, 4, 6, 8, 10, null]) {
67+
// The sequence is `10 * (2 ** (2 * n))` where n is 1, 2, 3...
68+
for (const delay of [40, 160, 640, 2560, 10240, null]) {
6869
try {
6970
return await (token
7071
? client.sendRequest(reqType, param, token)
@@ -84,8 +85,7 @@ export async function sendRequestWithRetry<TParam, TRet>(
8485
log.warn("LSP request failed", { method: reqType.method, param, error });
8586
throw error;
8687
}
87-
88-
await sleep(10 * (1 << delay));
88+
await sleep(delay);
8989
}
9090
}
9191
throw 'unreachable';

0 commit comments

Comments
 (0)