From cdd7118cbf23e21c376092b3b2734407004b8dbf Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Mon, 30 Dec 2019 22:53:21 +0100 Subject: Don't request inline hints repeatedly --- editors/code/src/ctx.ts | 13 ++++++++----- editors/code/src/inlay_hints.ts | 23 ++++++++++++++++++----- 2 files changed, 26 insertions(+), 10 deletions(-) (limited to 'editors') diff --git a/editors/code/src/ctx.ts b/editors/code/src/ctx.ts index 75b3542f4..d3ef27e43 100644 --- a/editors/code/src/ctx.ts +++ b/editors/code/src/ctx.ts @@ -62,20 +62,23 @@ export class Ctx { this.extCtx.subscriptions.push(d); } - async sendRequestWithRetry(method: string, param: any): Promise { + async sendRequestWithRetry(method: string, param: any, token: vscode.CancellationToken): Promise { await this.client.onReady(); - const nRetries = 3; - for (let triesLeft = nRetries; ; triesLeft--) { + for (const delay of [2, 4, 6, 8, 10, null]) { try { - return await this.client.sendRequest(method, param); + return await this.client.sendRequest(method, param, token); } catch (e) { - if (e.code === lc.ErrorCodes.ContentModified && triesLeft > 0) { + if (e.code === lc.ErrorCodes.ContentModified && delay !== null) { + await sleep(10 * (1 << delay)) continue; } throw e; } } + throw 'unreachable' } } export type Cmd = (...args: any[]) => any; + +const sleep = (ms: number) => new Promise(resolve => setTimeout(resolve, ms)) diff --git a/editors/code/src/inlay_hints.ts b/editors/code/src/inlay_hints.ts index 16faea22e..d41297407 100644 --- a/editors/code/src/inlay_hints.ts +++ b/editors/code/src/inlay_hints.ts @@ -41,6 +41,7 @@ const typeHintDecorationType = vscode.window.createTextEditorDecorationType({ }); class HintsUpdater { + private pending: Map = new Map(); private ctx: Ctx; private enabled = true; @@ -67,7 +68,8 @@ class HintsUpdater { private async refreshEditor(editor: vscode.TextEditor): Promise { const newHints = await this.queryHints(editor.document.uri.toString()); - const newDecorations = (newHints ? newHints : []).map(hint => ({ + if (newHints == null) return; + const newDecorations = newHints.map(hint => ({ range: hint.range, renderOptions: { after: { @@ -98,9 +100,20 @@ class HintsUpdater { const request: InlayHintsParams = { textDocument: { uri: documentUri }, }; - return this.ctx.sendRequestWithRetry( - 'rust-analyzer/inlayHints', - request, - ); + let tokenSource = new vscode.CancellationTokenSource(); + let prev = this.pending.get(documentUri); + if (prev) prev.cancel() + this.pending.set(documentUri, tokenSource); + try { + return await this.ctx.sendRequestWithRetry( + 'rust-analyzer/inlayHints', + request, + tokenSource.token, + ); + } finally { + if (!tokenSource.token.isCancellationRequested) { + this.pending.delete(documentUri) + } + } } } -- cgit v1.2.3