From e4b5bccf9364a0f678606d5bdfc18800854bf678 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Mon, 15 Apr 2019 11:34:55 -0700 Subject: [PATCH] Improve terminal launch --- .../api/browser/mainThreadTerminalService.ts | 2 ++ .../terminal/browser/terminalService.ts | 4 ++- .../contrib/terminal/common/terminal.ts | 1 + .../common/terminalProcessExtHostProxy.ts | 11 ++------ .../terminal/common/terminalService.ts | 28 +++++++++++++------ .../electron-browser/terminalService.ts | 6 ++-- 6 files changed, 31 insertions(+), 21 deletions(-) diff --git a/src/vs/workbench/api/browser/mainThreadTerminalService.ts b/src/vs/workbench/api/browser/mainThreadTerminalService.ts index 85cdee88e32..ba53e31e444 100644 --- a/src/vs/workbench/api/browser/mainThreadTerminalService.ts +++ b/src/vs/workbench/api/browser/mainThreadTerminalService.ts @@ -51,6 +51,8 @@ export class MainThreadTerminalService implements MainThreadTerminalServiceShape if (activeInstance) { this._proxy.$acceptActiveTerminalChanged(activeInstance.id); } + + this.terminalService.extHostReady(extHostContext.remoteAuthority); } public dispose(): void { diff --git a/src/vs/workbench/contrib/terminal/browser/terminalService.ts b/src/vs/workbench/contrib/terminal/browser/terminalService.ts index edd7e5d2478..f280a830240 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalService.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalService.ts @@ -22,6 +22,7 @@ import { IExtensionService } from 'vs/workbench/services/extensions/common/exten import { IFileService } from 'vs/platform/files/common/files'; import { TerminalInstance } from 'vs/workbench/contrib/terminal/browser/terminalInstance'; import { IBrowserTerminalConfigHelper } from 'vs/workbench/contrib/terminal/browser/terminal'; +import { IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteAgentService'; export abstract class TerminalService extends CommonTerminalService implements ITerminalService { protected _configHelper: IBrowserTerminalConfigHelper; @@ -38,8 +39,9 @@ export abstract class TerminalService extends CommonTerminalService implements I @IWorkbenchEnvironmentService private _environmentService: IWorkbenchEnvironmentService, @IExtensionService extensionService: IExtensionService, @IFileService fileService: IFileService, + @IRemoteAgentService remoteAgentService: IRemoteAgentService ) { - super(contextKeyService, panelService, lifecycleService, storageService, notificationService, dialogService, extensionService, fileService); + super(contextKeyService, panelService, lifecycleService, storageService, notificationService, dialogService, extensionService, fileService, remoteAgentService); } protected abstract _getDefaultShell(p: platform.Platform): string; diff --git a/src/vs/workbench/contrib/terminal/common/terminal.ts b/src/vs/workbench/contrib/terminal/common/terminal.ts index b4d9e485a14..c1f58a7fc8f 100644 --- a/src/vs/workbench/contrib/terminal/common/terminal.ts +++ b/src/vs/workbench/contrib/terminal/common/terminal.ts @@ -267,6 +267,7 @@ export interface ITerminalService { */ preparePathForTerminalAsync(path: string, executable: string | undefined, title: string): Promise; + extHostReady(remoteAuthority: string): void; requestExtHostProcess(proxy: ITerminalProcessExtHostProxy, shellLaunchConfig: IShellLaunchConfig, activeWorkspaceRootUri: URI, cols: number, rows: number): void; } diff --git a/src/vs/workbench/contrib/terminal/common/terminalProcessExtHostProxy.ts b/src/vs/workbench/contrib/terminal/common/terminalProcessExtHostProxy.ts index ed89adc9c7d..4fb3bd1e70f 100644 --- a/src/vs/workbench/contrib/terminal/common/terminalProcessExtHostProxy.ts +++ b/src/vs/workbench/contrib/terminal/common/terminalProcessExtHostProxy.ts @@ -7,7 +7,6 @@ import { Event, Emitter } from 'vs/base/common/event'; import { ITerminalService, ITerminalProcessExtHostProxy, IShellLaunchConfig, ITerminalChildProcess } from 'vs/workbench/contrib/terminal/common/terminal'; import { IDisposable } from 'vs/base/common/lifecycle'; import { URI } from 'vs/base/common/uri'; -import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions'; export class TerminalProcessExtHostProxy implements ITerminalChildProcess, ITerminalProcessExtHostProxy { private _disposables: IDisposable[] = []; @@ -44,15 +43,9 @@ export class TerminalProcessExtHostProxy implements ITerminalChildProcess, ITerm activeWorkspaceRootUri: URI, cols: number, rows: number, - @ITerminalService private readonly _terminalService: ITerminalService, - @IExtensionService private readonly _extensionService: IExtensionService + @ITerminalService private readonly _terminalService: ITerminalService ) { - this._extensionService.whenInstalledExtensionsRegistered().then(() => { - // TODO: MainThreadTerminalService is not ready at this point, fix this - setTimeout(() => { - this._terminalService.requestExtHostProcess(this, shellLaunchConfig, activeWorkspaceRootUri, cols, rows); - }, 0); - }); + this._terminalService.requestExtHostProcess(this, shellLaunchConfig, activeWorkspaceRootUri, cols, rows); } public dispose(): void { diff --git a/src/vs/workbench/contrib/terminal/common/terminalService.ts b/src/vs/workbench/contrib/terminal/common/terminalService.ts index a7cafd24d03..1b973709755 100644 --- a/src/vs/workbench/contrib/terminal/common/terminalService.ts +++ b/src/vs/workbench/contrib/terminal/common/terminalService.ts @@ -19,6 +19,8 @@ import { IFileService } from 'vs/platform/files/common/files'; import { escapeNonWindowsPath } from 'vs/workbench/contrib/terminal/common/terminalEnvironment'; import { isWindows } from 'vs/base/common/platform'; import { basename } from 'vs/base/common/path'; +import { IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteAgentService'; +import { timeout } from 'vs/base/common/async'; export abstract class TerminalService implements ITerminalService { public _serviceBrand: any; @@ -32,7 +34,7 @@ export abstract class TerminalService implements ITerminalService { return this._terminalTabs.reduce((p, c) => p.concat(c.terminalInstances), []); } private _findState: FindReplaceState; - + private _extHostsReady: { [authority: string]: boolean } = {}; private _activeTabIndex: number; public get activeTabIndex(): number { return this._activeTabIndex; } @@ -65,12 +67,13 @@ export abstract class TerminalService implements ITerminalService { constructor( @IContextKeyService private readonly _contextKeyService: IContextKeyService, @IPanelService protected readonly _panelService: IPanelService, - @ILifecycleService lifecycleService: ILifecycleService, + @ILifecycleService readonly lifecycleService: ILifecycleService, @IStorageService protected readonly _storageService: IStorageService, @INotificationService protected readonly _notificationService: INotificationService, @IDialogService private readonly _dialogService: IDialogService, @IExtensionService private readonly _extensionService: IExtensionService, - @IFileService protected readonly _fileService: IFileService + @IFileService protected readonly _fileService: IFileService, + @IRemoteAgentService readonly _remoteAgentService: IRemoteAgentService ) { this._activeTabIndex = 0; this._isShuttingDown = false; @@ -116,15 +119,22 @@ export abstract class TerminalService implements ITerminalService { } public requestExtHostProcess(proxy: ITerminalProcessExtHostProxy, shellLaunchConfig: IShellLaunchConfig, activeWorkspaceRootUri: URI, cols: number, rows: number): void { - // Ensure extension host is ready before requesting a process - this._extensionService.whenInstalledExtensionsRegistered().then(() => { - // TODO: MainThreadTerminalService is not ready at this point, fix this - setTimeout(() => { - this._onInstanceRequestExtHostProcess.fire({ proxy, shellLaunchConfig, activeWorkspaceRootUri, cols, rows }); - }, 500); + this._extensionService.whenInstalledExtensionsRegistered().then(async () => { + // Wait for the remoteAuthority to be ready (and listening for events) before proceeding + const conn = this._remoteAgentService.getConnection(); + const remoteAuthority = conn ? conn.remoteAuthority : 'null'; + let retries = 0; + while (!this._extHostsReady[remoteAuthority] && ++retries < 50) { + await timeout(100); + } + this._onInstanceRequestExtHostProcess.fire({ proxy, shellLaunchConfig, activeWorkspaceRootUri, cols, rows }); }); } + public extHostReady(remoteAuthority: string): void { + this._extHostsReady[remoteAuthority] = true; + } + private _onBeforeShutdown(): boolean | Promise { if (this.terminalInstances.length === 0) { // No terminal instances, don't veto diff --git a/src/vs/workbench/contrib/terminal/electron-browser/terminalService.ts b/src/vs/workbench/contrib/terminal/electron-browser/terminalService.ts index c24f3ffdb8c..d7e3026986e 100644 --- a/src/vs/workbench/contrib/terminal/electron-browser/terminalService.ts +++ b/src/vs/workbench/contrib/terminal/electron-browser/terminalService.ts @@ -28,6 +28,7 @@ import { IFileService } from 'vs/platform/files/common/files'; import { escapeNonWindowsPath } from 'vs/workbench/contrib/terminal/common/terminalEnvironment'; import { execFile } from 'child_process'; import { URI } from 'vs/base/common/uri'; +import { IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteAgentService'; export class TerminalService extends BrowserTerminalService implements ITerminalService { public get configHelper(): ITerminalConfigHelper { return this._configHelper; } @@ -45,9 +46,10 @@ export class TerminalService extends BrowserTerminalService implements ITerminal @IDialogService dialogService: IDialogService, @IExtensionService extensionService: IExtensionService, @IWorkbenchEnvironmentService environmentService: IWorkbenchEnvironmentService, - @IFileService fileService: IFileService + @IFileService fileService: IFileService, + @IRemoteAgentService remoteAgentService: IRemoteAgentService ) { - super(contextKeyService, panelService, layoutService, lifecycleService, storageService, notificationService, dialogService, instantiationService, environmentService, extensionService, fileService); + super(contextKeyService, panelService, layoutService, lifecycleService, storageService, notificationService, dialogService, instantiationService, environmentService, extensionService, fileService, remoteAgentService); this._configHelper = this._instantiationService.createInstance(TerminalConfigHelper, linuxDistro); ipc.on('vscode:openFiles', (_event: any, request: IOpenFileRequest) => { -- GitLab