mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-24 12:03:31 +00:00
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.
This commit is contained in:
parent
a69f19a6a5
commit
e43811c164
2 changed files with 13 additions and 3 deletions
|
@ -337,6 +337,16 @@ impl GlobalState {
|
||||||
fn on_request(&mut self, request_received: Instant, req: Request) -> Result<()> {
|
fn on_request(&mut self, request_received: Instant, req: Request) -> Result<()> {
|
||||||
self.register_request(&req, request_received);
|
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 }
|
RequestDispatcher { req: Some(req), global_state: self }
|
||||||
.on_sync::<lsp_ext::ReloadWorkspace>(|s, ()| Ok(s.fetch_workspaces()))?
|
.on_sync::<lsp_ext::ReloadWorkspace>(|s, ()| Ok(s.fetch_workspaces()))?
|
||||||
.on_sync::<lsp_ext::JoinLines>(|s, p| handlers::handle_join_lines(s.snapshot(), p))?
|
.on_sync::<lsp_ext::JoinLines>(|s, p| handlers::handle_join_lines(s.snapshot(), p))?
|
||||||
|
|
|
@ -64,7 +64,8 @@ export async function sendRequestWithRetry<TParam, TRet>(
|
||||||
param: TParam,
|
param: TParam,
|
||||||
token?: vscode.CancellationToken,
|
token?: vscode.CancellationToken,
|
||||||
): Promise<TRet> {
|
): 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 {
|
try {
|
||||||
return await (token
|
return await (token
|
||||||
? client.sendRequest(reqType, param, 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 });
|
log.warn("LSP request failed", { method: reqType.method, param, error });
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
|
await sleep(delay);
|
||||||
await sleep(10 * (1 << delay));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
throw 'unreachable';
|
throw 'unreachable';
|
||||||
|
|
Loading…
Reference in a new issue