Add restart TypeScript Server logic (#23877)

* Add restart TypeScript Server logic

**bug**
Currently, we often have to reload VSCode when we need to restart the TSserver to enable logging or change typescript versions

**Fix**
Add a way to restart the TSServer

* Remove old command

* Formatting
This commit is contained in:
Matt Bierner
2017-04-07 15:19:23 -07:00
committed by GitHub
parent 51d3ae8a72
commit d4dc61b684
2 changed files with 66 additions and 47 deletions

View File

@@ -443,6 +443,15 @@ class TypeScriptServiceClientHost implements ITypescriptServiceClientHost {
return this.client;
}
public restartTsServer(): void {
this.client.restartTsServer();
if (this.languages) {
for (const provider of this.languages) {
provider.reInitialize();
}
}
}
public reloadProjects(): void {
this.client.execute('reloadProjects', null, false);
this.triggerAllDiagnostics();

View File

@@ -144,7 +144,7 @@ export default class TypeScriptServiceClient implements ITypescriptServiceClient
private _output: OutputChannel;
private tsServerLogFile: string | null = null;
private tsServerLogLevel: TsServerLogLevel = TsServerLogLevel.Off;
private servicePromise: Promise<cp.ChildProcess> | null;
private servicePromise: Thenable<cp.ChildProcess> | null;
private lastError: Error | null;
private reader: Reader<Proto.Response>;
private sequenceNumber: number;
@@ -211,21 +211,8 @@ export default class TypeScriptServiceClient implements ITypescriptServiceClient
if (this.servicePromise === null && (oldglobalTsdk !== this.globalTsdk || oldLocalTsdk !== this.localTsdk)) {
this.startService();
} else if (this.servicePromise !== null && this.tsServerLogLevel !== oldLoggingLevel) {
const reloadItem = { title: localize('reloadTitle', 'Reload') };
window.showInformationMessage<MessageItem>(
localize('tsserverLogReloadBlurb', 'Reload VS Code to apply \'typescript.tsserver.log\' change'),
reloadItem,
{
title: localize('later', 'Later'),
isCloseAffordance: true
})
.then(selected => {
if (selected === reloadItem) {
commands.executeCommand('workbench.action.reloadWindow');
}
});
} else if (this.servicePromise !== null && (this.tsServerLogLevel !== oldLoggingLevel || (oldglobalTsdk !== this.globalTsdk || oldLocalTsdk !== this.localTsdk))) {
this.promptUserToRestartTsServer();
}
}));
if (this.packageInfo && this.packageInfo.aiKey) {
@@ -235,6 +222,41 @@ export default class TypeScriptServiceClient implements ITypescriptServiceClient
this.startService();
}
public restartTsServer(): void {
const start = () => {
this.trace = this.readTrace();
this.tsServerLogLevel = this.readTsServerLogLevel();
this.servicePromise = this.startService();
return this.servicePromise;
};
if (this.servicePromise !== null) {
this.servicePromise = this.servicePromise.then(cp => {
if (cp) {
cp.kill();
}
}).then(start);
} else {
start();
}
}
private promptUserToRestartTsServer(): void {
const restartItem = { title: localize('restartTsServerTitle', 'Restart') };
window.showInformationMessage<MessageItem>(
localize('restartTypeScriptServerBlurb', 'Restart TypeScript Server to apply change'),
restartItem,
{
title: localize('later', 'Later'),
isCloseAffordance: true
})
.then(selected => {
if (selected === restartItem) {
this.restartTsServer();
}
});
}
private extractGlobalTsdk(configuration: WorkspaceConfiguration): string | null {
let inspect = configuration.inspect('typescript.tsdk');
if (inspect && inspect.globalValue && 'string' === typeof inspect.globalValue) {
@@ -382,7 +404,7 @@ export default class TypeScriptServiceClient implements ITypescriptServiceClient
}
}
private service(): Promise<cp.ChildProcess> {
private service(): Thenable<cp.ChildProcess> {
if (this.servicePromise) {
return this.servicePromise;
}
@@ -441,7 +463,7 @@ export default class TypeScriptServiceClient implements ITypescriptServiceClient
return !!this.localTsdk;
}
private startService(resendModels: boolean = false): void {
private startService(resendModels: boolean = false): Thenable<cp.ChildProcess> {
let modulePath: Thenable<string> = Promise.resolve(this.globalTypescriptPath);
if (!this.workspaceState.get<boolean>(TypeScriptServiceClient.tsdkMigratedStorageKey, false)) {
@@ -451,7 +473,7 @@ export default class TypeScriptServiceClient implements ITypescriptServiceClient
}
}
modulePath.then(modulePath => {
return modulePath.then(modulePath => {
if (this.workspaceState.get<boolean>(TypeScriptServiceClient.useWorkspaceTsdkStorageKey, false)) {
if (workspace.rootPath) {
// TODO: check if we need better error handling
@@ -460,7 +482,7 @@ export default class TypeScriptServiceClient implements ITypescriptServiceClient
}
return modulePath;
}).then(modulePath => {
this.servicePromise = new Promise<cp.ChildProcess>((resolve, reject) => {
return this.servicePromise = new Promise<cp.ChildProcess>((resolve, reject) => {
const tsConfig = workspace.getConfiguration('typescript');
this.info(`Using tsserver from location: ${modulePath}`);
@@ -618,20 +640,7 @@ export default class TypeScriptServiceClient implements ITypescriptServiceClient
if (firstRun || newModulePath === this.modulePath) {
return;
}
const reloadMessage = { title: localize('reloadTitle', 'Reload') };
window.showInformationMessage<MessageItem>(
localize('reloadBlurb', 'Reload window to apply changes'),
reloadMessage,
{
title: localize('later', 'Later'),
isCloseAffordance: true
})
.then(selected => {
if (selected === reloadMessage) {
commands.executeCommand('workbench.action.reloadWindow');
}
});
this.promptUserToRestartTsServer();
};
return window.showQuickPick<MyQuickPickItem>(pickOptions, {
@@ -681,16 +690,16 @@ export default class TypeScriptServiceClient implements ITypescriptServiceClient
return window.showErrorMessage<MessageItem>(
localize(
'typescript.openTsServerLog.loggingNotEnabled',
'TS Server logging is off. Please set `typescript.tsserver.log` and reload VS Code to enable logging'),
'TS Server logging is off. Please set `typescript.tsserver.log` and restart the TS server to enable logging'),
{
title: localize(
'typescript.openTsServerLog.enableAndReloadOption',
'Enable logging and reload VS Code'),
'Enable logging and restart TS server'),
})
.then(selection => {
if (selection) {
return workspace.getConfiguration().update('typescript.tsserver.log', 'verbose', true).then(() => {
commands.executeCommand('workbench.action.reloadWindow');
this.restartTsServer();
return false;
});
}
@@ -916,16 +925,17 @@ export default class TypeScriptServiceClient implements ITypescriptServiceClient
this.callbacks[serverRequest.seq] = requestItem.callbacks;
this.pendingResponses++;
}
this.service().then((childProcess) => {
childProcess.stdin.write(JSON.stringify(serverRequest) + '\r\n', 'utf8');
}).catch(err => {
let callback = this.callbacks[serverRequest.seq];
if (callback) {
callback.e(err);
delete this.callbacks[serverRequest.seq];
this.pendingResponses--;
}
});
this.service()
.then((childProcess) => {
childProcess.stdin.write(JSON.stringify(serverRequest) + '\r\n', 'utf8');
}).then(undefined, err => {
let callback = this.callbacks[serverRequest.seq];
if (callback) {
callback.e(err);
delete this.callbacks[serverRequest.seq];
this.pendingResponses--;
}
});
}
private tryCancelRequest(seq: number): boolean {