Skip to content

Commit 4e5de4b

Browse files
committed
debounce and queue decoration request, fixes microsoft#40210
1 parent 6cb8c4c commit 4e5de4b

3 files changed

Lines changed: 75 additions & 11 deletions

File tree

src/vs/workbench/api/electron-browser/mainThreadDecorations.ts

Lines changed: 52 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,21 +7,69 @@
77
import URI, { UriComponents } from 'vs/base/common/uri';
88
import { Emitter } from 'vs/base/common/event';
99
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
10-
import { ExtHostContext, MainContext, IExtHostContext, MainThreadDecorationsShape, ExtHostDecorationsShape } from '../node/extHost.protocol';
10+
import { ExtHostContext, MainContext, IExtHostContext, MainThreadDecorationsShape, ExtHostDecorationsShape, DecorationData, DecorationRequest } from '../node/extHost.protocol';
1111
import { extHostNamedCustomer } from 'vs/workbench/api/electron-browser/extHostCustomers';
1212
import { IDecorationsService, IDecorationData } from 'vs/workbench/services/decorations/browser/decorations';
1313

14+
class DecorationRequestsQueue {
15+
16+
private _idPool = 0;
17+
private _requests: DecorationRequest[] = [];
18+
private _resolver: { [id: number]: Function } = Object.create(null);
19+
20+
private _timer: number;
21+
22+
constructor(
23+
private _proxy: ExtHostDecorationsShape
24+
) {
25+
//
26+
}
27+
28+
enqueue(handle: number, uri: URI): Thenable<DecorationData> {
29+
return new Promise((resolve, reject) => {
30+
const id = ++this._idPool;
31+
this._requests.push({ id, handle, uri });
32+
this._resolver[id] = resolve;
33+
this._processQueue();
34+
});
35+
}
36+
37+
private _processQueue(): void {
38+
if (typeof this._timer === 'number') {
39+
// already queued
40+
return;
41+
}
42+
this._timer = setTimeout(() => {
43+
// make request
44+
const requests = this._requests;
45+
const resolver = this._resolver;
46+
this._proxy.$provideDecorations(requests).then(data => {
47+
for (const id in resolver) {
48+
resolver[id](data[id]);
49+
}
50+
});
51+
52+
// reset
53+
this._requests = [];
54+
this._resolver = [];
55+
this._timer = void 0;
56+
}, 0);
57+
}
58+
}
59+
1460
@extHostNamedCustomer(MainContext.MainThreadDecorations)
1561
export class MainThreadDecorations implements MainThreadDecorationsShape {
1662

1763
private readonly _provider = new Map<number, [Emitter<URI[]>, IDisposable]>();
1864
private readonly _proxy: ExtHostDecorationsShape;
65+
private readonly _requestQueue: DecorationRequestsQueue;
1966

2067
constructor(
2168
context: IExtHostContext,
2269
@IDecorationsService private readonly _decorationsService: IDecorationsService
2370
) {
2471
this._proxy = context.getProxy(ExtHostContext.ExtHostDecorations);
72+
this._requestQueue = new DecorationRequestsQueue(this._proxy);
2573
}
2674

2775
dispose() {
@@ -30,12 +78,12 @@ export class MainThreadDecorations implements MainThreadDecorationsShape {
3078
}
3179

3280
$registerDecorationProvider(handle: number, label: string): void {
33-
let emitter = new Emitter<URI[]>();
34-
let registration = this._decorationsService.registerDecorationsProvider({
81+
const emitter = new Emitter<URI[]>();
82+
const registration = this._decorationsService.registerDecorationsProvider({
3583
label,
3684
onDidChange: emitter.event,
3785
provideDecorations: (uri) => {
38-
return this._proxy.$provideDecorations(handle, uri).then(data => {
86+
return this._requestQueue.enqueue(handle, uri).then(data => {
3987
if (!data) {
4088
return undefined;
4189
}

src/vs/workbench/api/node/extHost.protocol.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -719,10 +719,17 @@ export interface ExtHostDebugServiceShape {
719719
}
720720

721721

722+
export interface DecorationRequest {
723+
readonly id: number;
724+
readonly handle: number;
725+
readonly uri: UriComponents;
726+
}
727+
722728
export type DecorationData = [number, boolean, string, string, ThemeColor, string];
729+
export type DecorationReply = { [id: number]: DecorationData };
723730

724731
export interface ExtHostDecorationsShape {
725-
$provideDecorations(handle: number, uri: UriComponents): TPromise<DecorationData>;
732+
$provideDecorations(requests: DecorationRequest[]): TPromise<DecorationReply>;
726733
}
727734

728735
export interface ExtHostWindowShape {

src/vs/workbench/api/node/extHostDecorations.ts

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@
55
'use strict';
66

77
import * as vscode from 'vscode';
8-
import URI, { UriComponents } from 'vs/base/common/uri';
9-
import { MainContext, IMainContext, ExtHostDecorationsShape, MainThreadDecorationsShape, DecorationData } from 'vs/workbench/api/node/extHost.protocol';
8+
import URI from 'vs/base/common/uri';
9+
import { MainContext, IMainContext, ExtHostDecorationsShape, MainThreadDecorationsShape, DecorationData, DecorationRequest, DecorationReply } from 'vs/workbench/api/node/extHost.protocol';
1010
import { TPromise } from 'vs/base/common/winjs.base';
1111
import { Disposable } from 'vs/workbench/api/node/extHostTypes';
1212
import { asWinJsPromise } from 'vs/base/common/async';
@@ -38,10 +38,19 @@ export class ExtHostDecorations implements ExtHostDecorationsShape {
3838
});
3939
}
4040

41-
$provideDecorations(handle: number, data: UriComponents): TPromise<DecorationData> {
42-
const provider = this._provider.get(handle);
43-
return asWinJsPromise(token => provider.provideDecoration(URI.revive(data), token)).then(data => {
44-
return data && <DecorationData>[data.priority, data.bubble, data.title, data.abbreviation, data.color, data.source];
41+
$provideDecorations(requests: DecorationRequest[]): TPromise<DecorationReply> {
42+
const result: DecorationReply = Object.create(null);
43+
return TPromise.join(requests.map(request => {
44+
const { handle, uri, id } = request;
45+
const provider = this._provider.get(handle);
46+
return asWinJsPromise(token => provider.provideDecoration(URI.revive(uri), token)).then(data => {
47+
result[id] = data && <DecorationData>[data.priority, data.bubble, data.title, data.abbreviation, data.color, data.source];
48+
}, err => {
49+
console.error(err);
50+
});
51+
52+
})).then(() => {
53+
return result;
4554
});
4655
}
4756
}

0 commit comments

Comments
 (0)