Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Consolidate local and remote terminal implementations #118252

Merged
merged 57 commits into from
Mar 9, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
57 commits
Select commit Hold shift + click to select a range
05ccfc4
Move localPtyService to node
Tyriar Mar 4, 2021
1370dac
Rename localPtyService to ptyHostService
Tyriar Mar 4, 2021
418b824
Progress towards sharing local and remote term impl
Tyriar Mar 5, 2021
aadc16a
Simplify channel comm
Tyriar Mar 5, 2021
7703dff
Clean up, bring local remote interfaces closer
Tyriar Mar 5, 2021
0bcba04
Make setTerminalLayoutInfo interface consistent
Tyriar Mar 5, 2021
e518e53
Share IOffProcessTerminalService
Tyriar Mar 5, 2021
df6b269
Support orphaned processes
Tyriar Mar 5, 2021
fe24a79
Support attach to session in local
Tyriar Mar 5, 2021
dfbc537
Increase local grace time to a minute
Tyriar Mar 5, 2021
ccb3601
Support term cli commands
Tyriar Mar 5, 2021
a7d9285
Update distro
Tyriar Mar 5, 2021
22cb8cc
Merge remote-tracking branch 'origin/main' into tyriar/116467_2
Tyriar Mar 5, 2021
7af259a
Add logs to test
Tyriar Mar 5, 2021
5d5fa58
Support pty host management in remote
Tyriar Mar 5, 2021
ff09362
Merge remote-tracking branch 'origin/main' into tyriar/116467_2
Tyriar Mar 5, 2021
6b2daa9
Update distro
Tyriar Mar 5, 2021
b15bbfa
More test logs
Tyriar Mar 6, 2021
c40b367
Merge remote-tracking branch 'origin/main' into tyriar/116467_2
Tyriar Mar 6, 2021
61ea6ad
Remote shell type support
Tyriar Mar 6, 2021
258ee03
Update distro
Tyriar Mar 6, 2021
755fae5
Bail out of create process if it's been disposed
Tyriar Mar 6, 2021
02a5d59
Disable relaunch in tests
Tyriar Mar 6, 2021
da79b9d
Don't setup pty host listeners twice in remote
Tyriar Mar 6, 2021
074632a
Try enable remote terminal integration tests
Tyriar Mar 6, 2021
11897d0
Disable pty host listeners temporarily
Tyriar Mar 6, 2021
5cc1775
Disable unresponsive create process
Tyriar Mar 7, 2021
74532eb
Re-enable process unresponsive checking
Tyriar Mar 7, 2021
4abc244
Add windows-process-tree to remote deps
Tyriar Mar 8, 2021
1cd624c
Merge remote-tracking branch 'origin/main' into tyriar/116467_2
Tyriar Mar 8, 2021
4d3b158
Disable terminal tests in remote again, fix settings for tasks
Tyriar Mar 8, 2021
b41b95f
Pin windows-process-tree@0.2.4 to match main package.json
Tyriar Mar 8, 2021
3f778f6
Update distro
Tyriar Mar 8, 2021
9022c7f
Update distro
Tyriar Mar 8, 2021
03c8548
Merge remote-tracking branch 'origin/main' into tyriar/116467_2
Tyriar Mar 8, 2021
d8a7202
Update distro
Tyriar Mar 8, 2021
45c032d
Skip the failing task test
Tyriar Mar 8, 2021
221e20b
Re-enable, add some more test logs
Tyriar Mar 8, 2021
23ad719
Log acceptTerminalOpened
Tyriar Mar 8, 2021
30f4163
Skip the failing test for remote only
Tyriar Mar 8, 2021
8fe29a7
Uncomment in test
Tyriar Mar 8, 2021
5fdbc82
Re-enable task and term test
Tyriar Mar 9, 2021
b62e3c7
Update distro
Tyriar Mar 9, 2021
09c3c2d
Remove broken part of test
Tyriar Mar 9, 2021
6d01ad9
Merge remote-tracking branch 'origin/main' into tyriar/116467_2
Tyriar Mar 9, 2021
d1dbb93
Remove remote test failure comment
Tyriar Mar 9, 2021
55af802
Simplify RemotePty, revive shell config cwd
Tyriar Mar 9, 2021
27efd88
Remove preconnection terminal concept
Tyriar Mar 9, 2021
ab9e11f
Remove resolved comments
Tyriar Mar 9, 2021
364b9e9
Merge remote-tracking branch 'origin/main' into tyriar/116467_2
Tyriar Mar 9, 2021
8785268
Update distro
Tyriar Mar 9, 2021
7bcec04
Comment out notebook compile error
Tyriar Mar 9, 2021
e7b0596
Revert "Comment out notebook compile error"
Tyriar Mar 9, 2021
1e7fbfa
Merge remote-tracking branch 'origin/main' into tyriar/116467_2
Tyriar Mar 9, 2021
6374970
Update distro
Tyriar Mar 9, 2021
4bb960a
Merge remote-tracking branch 'origin/main' into tyriar/116467_2
Tyriar Mar 9, 2021
dc92ff5
Set distro back to that in main
Tyriar Mar 9, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,7 @@ import { assertNoRpc } from '../utils';

// Disable terminal tests:
// - Web https://github.com/microsoft/vscode/issues/92826
// - Remote https://github.com/microsoft/vscode/issues/96057
((env.uiKind === UIKind.Web || typeof env.remoteName !== 'undefined') ? suite.skip : suite)('vscode API - terminal', () => {
(env.uiKind === UIKind.Web ? suite.skip : suite)('vscode API - terminal', () => {
let extensionContext: ExtensionContext;

suiteSetup(async () => {
Expand All @@ -25,6 +24,8 @@ import { assertNoRpc } from '../utils';
await config.update('showExitAlert', false, ConfigurationTarget.Global);
// Canvas may cause problems when running in a container
await config.update('rendererType', 'dom', ConfigurationTarget.Global);
// Disable env var relaunch for tests to prevent terminals relaunching themselves
await config.update('environmentChangesRelaunch', false, ConfigurationTarget.Global);
});

suite('Terminal', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,25 @@
*--------------------------------------------------------------------------------------------*/

import * as assert from 'assert';
import { window, tasks, Disposable, TaskDefinition, Task, EventEmitter, CustomExecution, Pseudoterminal, TaskScope, commands, env, UIKind, ShellExecution, TaskExecution, Terminal, Event } from 'vscode';
import { window, tasks, Disposable, TaskDefinition, Task, EventEmitter, CustomExecution, Pseudoterminal, TaskScope, commands, env, UIKind, ShellExecution, TaskExecution, Terminal, Event, workspace, ConfigurationTarget } from 'vscode';
import { assertNoRpc } from '../utils';

// Disable tasks tests:
// - Web https://github.com/microsoft/vscode/issues/90528
((env.uiKind === UIKind.Web) ? suite.skip : suite)('vscode API - tasks', () => {

suiteSetup(async () => {
const config = workspace.getConfiguration('terminal.integrated');
// Disable conpty in integration tests because of https://github.com/microsoft/vscode/issues/76548
await config.update('windowsEnableConpty', false, ConfigurationTarget.Global);
// Disable exit alerts as tests may trigger then and we're not testing the notifications
await config.update('showExitAlert', false, ConfigurationTarget.Global);
// Canvas may cause problems when running in a container
await config.update('rendererType', 'dom', ConfigurationTarget.Global);
// Disable env var relaunch for tests to prevent terminals relaunching themselves
await config.update('environmentChangesRelaunch', false, ConfigurationTarget.Global);
});

suite('Tasks', () => {
let disposables: Disposable[] = [];

Expand Down Expand Up @@ -206,7 +218,6 @@ import { assertNoRpc } from '../utils';
progressMade.fire();
}
}));

taskExecution = await tasks.executeTask(task);
executeDoneEvent.fire();
});
Expand Down
3 changes: 2 additions & 1 deletion remote/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
},
"optionalDependencies": {
"vscode-windows-ca-certs": "0.3.0",
"vscode-windows-registry": "1.0.2"
"vscode-windows-registry": "1.0.2",
"windows-process-tree": "0.2.4"
}
}
12 changes: 12 additions & 0 deletions remote/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,11 @@ ms@^2.1.1:
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009"
integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==

nan@^2.13.2:
version "2.14.2"
resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.2.tgz#f5376400695168f4cc694ac9393d0c9585eeea19"
integrity sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ==

nan@^2.14.0:
version "2.14.0"
resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.0.tgz#7818f722027b2459a86f0295d434d1fc2336c52c"
Expand Down Expand Up @@ -411,6 +416,13 @@ vscode-windows-registry@1.0.2:
resolved "https://registry.yarnpkg.com/vscode-windows-registry/-/vscode-windows-registry-1.0.2.tgz#b863e704a6a69c50b3098a55fbddbe595b0c124a"
integrity sha512-/CLLvuOSM2Vme2z6aNyB+4Omd7hDxpf4Thrt8ImxnXeQtxzel2bClJpFQvQqK/s4oaXlkBKS7LqVLeZM+uSVIA==

windows-process-tree@0.2.4:
version "0.2.4"
resolved "https://registry.yarnpkg.com/windows-process-tree/-/windows-process-tree-0.2.4.tgz#747af587b54cc6c996f2be0836cc8a8fd0dc038f"
integrity sha512-9gag9AHm3Iin/4YC1EwoIfZlqW/rG2eV7rJZ4Fy5NnAMGdewmnwsie5Rz+CJo2vSolqzzfw7hPeu3oOdniNejg==
dependencies:
nan "^2.13.2"

xterm-addon-search@0.8.0:
version "0.8.0"
resolved "https://registry.yarnpkg.com/xterm-addon-search/-/xterm-addon-search-0.8.0.tgz#e33eab918df7eac7e7baf95dd2b3d14133754881"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ import { onUnexpectedError, setUnexpectedErrorHandler } from 'vs/base/common/err
import { toErrorMessage } from 'vs/base/common/errorMessage';
import { join } from 'vs/base/common/path';
import { TerminalIpcChannels } from 'vs/platform/terminal/common/terminal';
import { LocalPtyService } from 'vs/platform/terminal/electron-browser/localPtyService';
import { PtyHostService } from 'vs/platform/terminal/node/ptyHostService';
import { ILocalPtyService } from 'vs/platform/terminal/electron-sandbox/terminal';
import { UserDataSyncChannel } from 'vs/platform/userDataSync/common/userDataSyncServiceIpc';
import { IChecksumService } from 'vs/platform/checksum/common/checksumService';
Expand Down Expand Up @@ -267,8 +267,7 @@ class SharedProcessMain extends Disposable {
services.set(IUserDataSyncService, new SyncDescriptor(UserDataSyncService));

// Terminal
const localPtyService = this._register(new LocalPtyService(logService));
services.set(ILocalPtyService, localPtyService);
services.set(ILocalPtyService, this._register(new PtyHostService(logService)));

return new InstantiationService(services);
}
Expand Down
28 changes: 19 additions & 9 deletions src/vs/platform/terminal/common/terminal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { createDecorator } from 'vs/platform/instantiation/common/instantiation'
import { Event } from 'vs/base/common/event';
import { IProcessEnvironment } from 'vs/base/common/platform';
import { URI } from 'vs/base/common/uri';
import { IGetTerminalLayoutInfoArgs, IPtyHostProcessReplayEvent, ISetTerminalLayoutInfoArgs } from 'vs/platform/terminal/common/terminalProcess';
import { IGetTerminalLayoutInfoArgs, IProcessDetails, IPtyHostProcessReplayEvent, ISetTerminalLayoutInfoArgs } from 'vs/platform/terminal/common/terminalProcess';

export enum WindowsShellType {
CommandPrompt = 'cmd',
Expand Down Expand Up @@ -76,8 +76,6 @@ export enum TerminalIpcChannels {
export interface IOffProcessTerminalService {
readonly _serviceBrand: undefined;

/** Fired when the ptyHost process goes down, losing all connections to the service's ptys. */
onPtyHostExit: Event<void>;
/**
* Fired when the ptyHost process becomes non-responsive, this should disable stdin for all
* terminals using this pty host connection and mark them as disconnected.
Expand All @@ -94,16 +92,18 @@ export interface IOffProcessTerminalService {
*/
onPtyHostRestart: Event<void>;

createTerminalProcess(shellLaunchConfig: IShellLaunchConfig, cwd: string, cols: number, rows: number, env: IProcessEnvironment, windowsEnableConpty: boolean, shouldPersist: boolean): Promise<ITerminalChildProcess>;
attachToProcess(id: number): Promise<ITerminalChildProcess | undefined>;
setTerminalLayoutInfo(args?: ISetTerminalLayoutInfoArgs): void;
setTerminalLayoutInfo(layout: ITerminalsLayoutInfoById): void;
listProcesses(reduceGraceTime?: boolean): Promise<IProcessDetails[]>;
setTerminalLayoutInfo(layoutInfo?: ITerminalsLayoutInfoById): Promise<void>;
getTerminalLayoutInfo(): Promise<ITerminalsLayoutInfo | undefined>;
}

export const ILocalTerminalService = createDecorator<ILocalTerminalService>('localTerminalService');
export interface ILocalTerminalService extends IOffProcessTerminalService { }
export interface ILocalTerminalService extends IOffProcessTerminalService {
createProcess(shellLaunchConfig: IShellLaunchConfig, cwd: string, cols: number, rows: number, env: IProcessEnvironment, windowsEnableConpty: boolean, shouldPersist: boolean): Promise<ITerminalChildProcess>;
}

export const IPtyService = createDecorator<IPtyService>('ptyService');
export interface IPtyService {
readonly _serviceBrand: undefined;

Expand All @@ -120,6 +120,7 @@ export interface IPtyService {
readonly onProcessOverrideDimensions: Event<{ id: number, event: ITerminalDimensionsOverride | undefined }>;
readonly onProcessResolvedShellLaunchConfig: Event<{ id: number, event: IShellLaunchConfig }>;
readonly onProcessReplay: Event<{ id: number, event: IPtyHostProcessReplayEvent }>;
readonly onProcessOrphanQuestion: Event<{ id: number }>;

restartPtyHost?(): Promise<void>;
shutdownAll?(): Promise<void>;
Expand All @@ -139,6 +140,13 @@ export interface IPtyService {
attachToProcess(id: number): Promise<void>;
detachFromProcess(id: number): Promise<void>;

/**
* Lists all orphaned processes, ie. those without a connected frontend.
* @param reduceGraceTime Whether to reduce the reconnection grace time for all orphaned
* terminals.
*/
listProcesses(reduceGraceTime: boolean): Promise<IProcessDetails[]>;

start(id: number): Promise<ITerminalLaunchError | undefined>;
shutdown(id: number, immediate: boolean): Promise<void>;
input(id: number, data: string): Promise<void>;
Expand All @@ -147,8 +155,10 @@ export interface IPtyService {
getCwd(id: number): Promise<string>;
getLatency(id: number): Promise<number>;
acknowledgeDataEvent(id: number, charCount: number): Promise<void>;
/** Confirm the process is _not_ an orphan. */
orphanQuestionReply(id: number): Promise<void>;

setTerminalLayoutInfo(args: ISetTerminalLayoutInfoArgs): void;
setTerminalLayoutInfo(args: ISetTerminalLayoutInfoArgs): Promise<void>;
getTerminalLayoutInfo(args: IGetTerminalLayoutInfoArgs): Promise<ITerminalsLayoutInfo | undefined>;
}

Expand Down Expand Up @@ -346,7 +356,7 @@ export const enum LocalReconnectConstants {
/**
* If there is no reconnection within this time-frame, consider the connection permanently closed...
*/
ReconnectionGraceTime = 30000, // 30 seconds
ReconnectionGraceTime = 60000, // 60 seconds
/**
* Maximal grace time between the first and the last reconnection...
*/
Expand Down
4 changes: 2 additions & 2 deletions src/vs/platform/terminal/common/terminalProcess.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ export interface IGetTerminalLayoutInfoArgs {
workspaceId: string;
}

export interface IPtyHostDescriptionDto {
export interface IProcessDetails {
id: number;
pid: number;
title: string;
Expand All @@ -67,7 +67,7 @@ export interface IPtyHostDescriptionDto {
isOrphan: boolean;
}

export type ITerminalTabLayoutInfoDto = IRawTerminalTabLayoutInfo<IPtyHostDescriptionDto>;
export type ITerminalTabLayoutInfoDto = IRawTerminalTabLayoutInfo<IProcessDetails>;

export interface ReplayEntry { cols: number; rows: number; data: string; }
export interface IPtyHostProcessReplayEvent {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { ProxyChannel } from 'vs/base/parts/ipc/common/ipc';
import { IProcessEnvironment } from 'vs/base/common/platform';
import { Emitter } from 'vs/base/common/event';
import { LogLevelChannelClient } from 'vs/platform/log/common/logIpc';
import { IGetTerminalLayoutInfoArgs, IPtyHostProcessReplayEvent, ISetTerminalLayoutInfoArgs } from 'vs/platform/terminal/common/terminalProcess';
import { IGetTerminalLayoutInfoArgs, IProcessDetails, IPtyHostProcessReplayEvent, ISetTerminalLayoutInfoArgs } from 'vs/platform/terminal/common/terminalProcess';

enum Constants {
MaxRestarts = 5
Expand All @@ -24,7 +24,11 @@ enum Constants {
*/
let lastPtyId = 0;

export class LocalPtyService extends Disposable implements IPtyService {
/**
* This service implements IPtyService by launching a pty host process, forwarding messages to and
* from the pty host process and manages the connection.
*/
export class PtyHostService extends Disposable implements IPtyService {
declare readonly _serviceBrand: undefined;

private _client: Client;
Expand Down Expand Up @@ -62,6 +66,8 @@ export class LocalPtyService extends Disposable implements IPtyService {
readonly onProcessOverrideDimensions = this._onProcessOverrideDimensions.event;
private readonly _onProcessResolvedShellLaunchConfig = this._register(new Emitter<{ id: number, event: IShellLaunchConfig }>());
readonly onProcessResolvedShellLaunchConfig = this._onProcessResolvedShellLaunchConfig.event;
private readonly _onProcessOrphanQuestion = this._register(new Emitter<{ id: number }>());
readonly onProcessOrphanQuestion = this._onProcessOrphanQuestion.event;

constructor(
@ILogService private readonly _logService: ILogService
Expand Down Expand Up @@ -122,6 +128,7 @@ export class LocalPtyService extends Disposable implements IPtyService {
this._register(proxy.onProcessOverrideDimensions(e => this._onProcessOverrideDimensions.fire(e)));
this._register(proxy.onProcessResolvedShellLaunchConfig(e => this._onProcessResolvedShellLaunchConfig.fire(e)));
this._register(proxy.onProcessReplay(e => this._onProcessReplay.fire(e)));
this._register(proxy.onProcessOrphanQuestion(e => this._onProcessOrphanQuestion.fire(e)));

return [client, proxy];
}
Expand All @@ -144,6 +151,9 @@ export class LocalPtyService extends Disposable implements IPtyService {
detachFromProcess(id: number): Promise<void> {
return this._proxy.detachFromProcess(id);
}
listProcesses(reduceGraceTime: boolean): Promise<IProcessDetails[]> {
return this._proxy.listProcesses(reduceGraceTime);
}

start(id: number): Promise<ITerminalLaunchError | undefined> {
return this._proxy.start(id);
Expand All @@ -169,7 +179,11 @@ export class LocalPtyService extends Disposable implements IPtyService {
getLatency(id: number): Promise<number> {
return this._proxy.getLatency(id);
}
setTerminalLayoutInfo(args: ISetTerminalLayoutInfoArgs): void {
orphanQuestionReply(id: number): Promise<void> {
return this._proxy.orphanQuestionReply(id);
}

setTerminalLayoutInfo(args: ISetTerminalLayoutInfoArgs): Promise<void> {
return this._proxy.setTerminalLayoutInfo(args);
}
async getTerminalLayoutInfo(args: IGetTerminalLayoutInfoArgs): Promise<ITerminalsLayoutInfo | undefined> {
Expand Down
Loading