Skip to content

Commit

Permalink
Make geterr async
Browse files Browse the repository at this point in the history
  • Loading branch information
mjbvz committed May 8, 2018
1 parent faec3b5 commit 3fc493a
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -310,7 +310,7 @@ export default class BufferSyncSupport {
const token = new CancellationTokenSource();

const getErr = this.pendingGetErr = {
request: this.client.execute('geterr', args, token.token)
request: this.client.executeAsync('geterr', args, token.token)
.then(undefined, () => { })
.then(() => {
if (this.pendingGetErr === getErr) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ export interface ITypeScriptServiceClient {
execute(command: 'open', args: Proto.OpenRequestArgs, expectedResult: boolean, token?: CancellationToken): Promise<any>;
execute(command: 'close', args: Proto.FileRequestArgs, expectedResult: boolean, token?: CancellationToken): Promise<any>;
execute(command: 'change', args: Proto.ChangeRequestArgs, expectedResult: boolean, token?: CancellationToken): Promise<any>;
execute(command: 'geterr', args: Proto.GeterrRequestArgs, expectedResult: boolean, token?: CancellationToken): Promise<any>;
execute(command: 'quickinfo', args: Proto.FileLocationRequestArgs, token?: CancellationToken): Promise<Proto.QuickInfoResponse>;
execute(command: 'completions', args: Proto.CompletionsRequestArgs, token?: CancellationToken): Promise<Proto.CompletionsResponse>;
execute(command: 'completionEntryDetails', args: Proto.CompletionDetailsRequestArgs, token?: CancellationToken): Promise<Proto.CompletionDetailsResponse>;
Expand Down Expand Up @@ -60,4 +59,6 @@ export interface ITypeScriptServiceClient {
execute(command: 'organizeImports', args: Proto.OrganizeImportsRequestArgs, token?: CancellationToken): Promise<Proto.OrganizeImportsResponse>;
execute(command: 'getOutliningSpans', args: Proto.FileRequestArgs, token: CancellationToken): Promise<Proto.OutliningSpansResponse>;
execute(command: string, args: any, expectedResult: boolean | CancellationToken, token?: CancellationToken): Promise<any>;

executeAsync(command: 'geterr', args: Proto.GeterrRequestArgs, token: CancellationToken): Promise<any>;
}
Original file line number Diff line number Diff line change
Expand Up @@ -42,37 +42,48 @@ interface CallbackItem {

class CallbackMap {
private readonly callbacks: Map<number, CallbackItem> = new Map();
private readonly asyncCallbacks: Map<number, CallbackItem> = new Map();
public pendingResponses: number = 0;

public destroy(e: any): void {
for (const callback of this.callbacks.values()) {
callback.e(e);
}
for (const callback of this.asyncCallbacks.values()) {
callback.e(e);
}
this.callbacks.clear();
this.pendingResponses = 0;
}

public add(seq: number, callback: CallbackItem) {
this.callbacks.set(seq, callback);
++this.pendingResponses;
public add(seq: number, callback: CallbackItem, isAsync: boolean) {
if (isAsync) {
this.asyncCallbacks.set(seq, callback);
} else {
this.callbacks.set(seq, callback);
++this.pendingResponses;
}
}

public fetch(seq: number): CallbackItem | undefined {
const callback = this.callbacks.get(seq);
const callback = this.callbacks.get(seq) || this.asyncCallbacks.get(seq);
this.delete(seq);
return callback;
}

private delete(seq: number) {
if (this.callbacks.delete(seq)) {
--this.pendingResponses;
} else {
this.asyncCallbacks.delete(seq);
}
}
}

interface RequestItem {
request: Proto.Request;
readonly request: Proto.Request;
callbacks: CallbackItem | null;
readonly isAsync: boolean;
}

class RequestQueue {
Expand Down Expand Up @@ -672,6 +683,10 @@ export default class TypeScriptServiceClient implements ITypeScriptServiceClient
return undefined;
}

public executeAsync(command: string, args: Proto.GeterrRequestArgs, token: CancellationToken): Promise<any> {
return this.executeImpl(command, args, { isAsync: true, token, expectsResult: true });
}

public execute(command: string, args: any, expectsResultOrToken?: boolean | CancellationToken): Promise<any> {
let token: CancellationToken | undefined = undefined;
let expectsResult = true;
Expand All @@ -680,19 +695,23 @@ export default class TypeScriptServiceClient implements ITypeScriptServiceClient
} else {
token = expectsResultOrToken;
}
return this.executeImpl(command, args, { isAsync: false, token, expectsResult });
}

private executeImpl(command: string, args: any, executeInfo: { isAsync: boolean, token?: CancellationToken, expectsResult: boolean }): Promise<any> {
const request = this.requestQueue.createRequest(command, args);
const requestInfo: RequestItem = {
request: request,
callbacks: null
callbacks: null,
isAsync: executeInfo.isAsync
};
let result: Promise<any>;
if (expectsResult) {
if (executeInfo.expectsResult) {
let wasCancelled = false;
result = new Promise<any>((resolve, reject) => {
requestInfo.callbacks = { c: resolve, e: reject, start: Date.now() };
if (token) {
token.onCancellationRequested(() => {
if (executeInfo.token) {
executeInfo.token.onCancellationRequested(() => {
wasCancelled = true;
this.tryCancelRequest(request.seq);
});
Expand Down Expand Up @@ -751,7 +770,7 @@ export default class TypeScriptServiceClient implements ITypeScriptServiceClient
const serverRequest = requestItem.request;
this.tracer.traceRequest(serverRequest, !!requestItem.callbacks, this.requestQueue.length);
if (requestItem.callbacks) {
this.callbacks.add(serverRequest.seq, requestItem.callbacks);
this.callbacks.add(serverRequest.seq, requestItem.callbacks, requestItem.isAsync);
}
this.service()
.then((childProcess) => {
Expand Down Expand Up @@ -820,8 +839,10 @@ export default class TypeScriptServiceClient implements ITypeScriptServiceClient
private dispatchEvent(event: Proto.Event) {
switch (event.event) {
case 'requestCompleted':
const p = this.callbacks.fetch((event as Proto.RequestCompletedEvent).body.request_seq);
const seq = (event as Proto.RequestCompletedEvent).body.request_seq;
const p = this.callbacks.fetch(seq);
if (p) {
this.tracer.traceRequestCompleted('requestCompleted', seq, p.start);
p.c(undefined);
}
break;
Expand Down
7 changes: 7 additions & 0 deletions extensions/typescript-language-features/src/utils/tracer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,13 @@ export default class Tracer {
this.logTrace(`Response received: ${response.command} (${response.request_seq}). Request took ${Date.now() - startTime} ms. Success: ${response.success} ${!response.success ? '. Message: ' + response.message : ''}`, data);
}

public traceRequestCompleted(command: string, request_seq: number, startTime: number): any {
if (this.trace === Trace.Off) {
return;
}
this.logTrace(`Async response received: ${command} (${request_seq}). Request took ${Date.now() - startTime} ms.`);
}

public traceEvent(event: Proto.Event): void {
if (this.trace === Trace.Off) {
return;
Expand Down

0 comments on commit 3fc493a

Please sign in to comment.