aboutsummaryrefslogtreecommitdiff
path: root/editors
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2019-12-30 21:53:21 +0000
committerAleksey Kladov <[email protected]>2019-12-30 21:53:21 +0000
commitcdd7118cbf23e21c376092b3b2734407004b8dbf (patch)
treebf53aac74110d30eba6da346e764e003ffd8b9c4 /editors
parent23bac120625ca96402426e241c91ed5f3d7ccc02 (diff)
Don't request inline hints repeatedly
Diffstat (limited to 'editors')
-rw-r--r--editors/code/src/ctx.ts13
-rw-r--r--editors/code/src/inlay_hints.ts23
2 files changed, 26 insertions, 10 deletions
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 {
62 this.extCtx.subscriptions.push(d); 62 this.extCtx.subscriptions.push(d);
63 } 63 }
64 64
65 async sendRequestWithRetry<R>(method: string, param: any): Promise<R> { 65 async sendRequestWithRetry<R>(method: string, param: any, token: vscode.CancellationToken): Promise<R> {
66 await this.client.onReady(); 66 await this.client.onReady();
67 const nRetries = 3; 67 for (const delay of [2, 4, 6, 8, 10, null]) {
68 for (let triesLeft = nRetries; ; triesLeft--) {
69 try { 68 try {
70 return await this.client.sendRequest(method, param); 69 return await this.client.sendRequest(method, param, token);
71 } catch (e) { 70 } catch (e) {
72 if (e.code === lc.ErrorCodes.ContentModified && triesLeft > 0) { 71 if (e.code === lc.ErrorCodes.ContentModified && delay !== null) {
72 await sleep(10 * (1 << delay))
73 continue; 73 continue;
74 } 74 }
75 throw e; 75 throw e;
76 } 76 }
77 } 77 }
78 throw 'unreachable'
78 } 79 }
79} 80}
80 81
81export type Cmd = (...args: any[]) => any; 82export type Cmd = (...args: any[]) => any;
83
84const 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({
41}); 41});
42 42
43class HintsUpdater { 43class HintsUpdater {
44 private pending: Map<string, vscode.CancellationTokenSource> = new Map();
44 private ctx: Ctx; 45 private ctx: Ctx;
45 private enabled = true; 46 private enabled = true;
46 47
@@ -67,7 +68,8 @@ class HintsUpdater {
67 68
68 private async refreshEditor(editor: vscode.TextEditor): Promise<void> { 69 private async refreshEditor(editor: vscode.TextEditor): Promise<void> {
69 const newHints = await this.queryHints(editor.document.uri.toString()); 70 const newHints = await this.queryHints(editor.document.uri.toString());
70 const newDecorations = (newHints ? newHints : []).map(hint => ({ 71 if (newHints == null) return;
72 const newDecorations = newHints.map(hint => ({
71 range: hint.range, 73 range: hint.range,
72 renderOptions: { 74 renderOptions: {
73 after: { 75 after: {
@@ -98,9 +100,20 @@ class HintsUpdater {
98 const request: InlayHintsParams = { 100 const request: InlayHintsParams = {
99 textDocument: { uri: documentUri }, 101 textDocument: { uri: documentUri },
100 }; 102 };
101 return this.ctx.sendRequestWithRetry<InlayHint[] | null>( 103 let tokenSource = new vscode.CancellationTokenSource();
102 'rust-analyzer/inlayHints', 104 let prev = this.pending.get(documentUri);
103 request, 105 if (prev) prev.cancel()
104 ); 106 this.pending.set(documentUri, tokenSource);
107 try {
108 return await this.ctx.sendRequestWithRetry<InlayHint[] | null>(
109 'rust-analyzer/inlayHints',
110 request,
111 tokenSource.token,
112 );
113 } finally {
114 if (!tokenSource.token.isCancellationRequested) {
115 this.pending.delete(documentUri)
116 }
117 }
105 } 118 }
106} 119}