mirror of
https://github.com/microsoft/vscode.git
synced 2026-04-29 21:11:38 +01:00
Explorations
This commit is contained in:
207
src/vs/platform/remote/common/remoteAgentConnection.ts
Normal file
207
src/vs/platform/remote/common/remoteAgentConnection.ts
Normal file
@@ -0,0 +1,207 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { Client, PersistentProtocol, ISocket } from 'vs/base/parts/ipc/common/ipc.net';
|
||||
import { generateUuid } from 'vs/base/common/uuid';
|
||||
import { RemoteAgentConnectionContext } from 'vs/platform/remote/common/remoteAgentEnvironment';
|
||||
import { Disposable } from 'vs/base/common/lifecycle';
|
||||
|
||||
export const enum ConnectionType {
|
||||
Management = 1,
|
||||
ExtensionHost = 2,
|
||||
Tunnel = 3,
|
||||
}
|
||||
|
||||
interface ISimpleConnectionOptions {
|
||||
isBuilt: boolean;
|
||||
commit: string | undefined;
|
||||
host: string;
|
||||
port: number;
|
||||
reconnectionToken: string;
|
||||
reconnectionProtocol: PersistentProtocol | null;
|
||||
webSocketFactory: IWebSocketFactory;
|
||||
}
|
||||
|
||||
export interface IConnectCallback {
|
||||
(err: any | undefined, socket: ISocket | undefined): void;
|
||||
}
|
||||
|
||||
export interface IWebSocketFactory {
|
||||
connect(host: string, port: number, query: string, callback: IConnectCallback): void;
|
||||
}
|
||||
|
||||
async function connectToRemoteExtensionHostAgent(options: ISimpleConnectionOptions, connectionType: ConnectionType, args: any | undefined): Promise<PersistentProtocol> {
|
||||
throw new Error(`Not implemented`);
|
||||
}
|
||||
|
||||
interface IManagementConnectionResult {
|
||||
protocol: PersistentProtocol;
|
||||
}
|
||||
|
||||
async function doConnectRemoteAgentManagement(options: ISimpleConnectionOptions): Promise<IManagementConnectionResult> {
|
||||
const protocol = await connectToRemoteExtensionHostAgent(options, ConnectionType.Management, undefined);
|
||||
return new Promise<IManagementConnectionResult>((c, e) => {
|
||||
const registration = protocol.onControlMessage(raw => {
|
||||
registration.dispose();
|
||||
const msg = JSON.parse(raw.toString());
|
||||
const error = getErrorFromMessage(msg);
|
||||
if (error) {
|
||||
return e(error);
|
||||
}
|
||||
if (options.reconnectionProtocol) {
|
||||
options.reconnectionProtocol.endAcceptReconnection();
|
||||
}
|
||||
c({ protocol });
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
export interface IRemoteExtensionHostStartParams {
|
||||
language: string;
|
||||
debugId?: string;
|
||||
break?: boolean;
|
||||
port?: number | null;
|
||||
updatePort?: boolean;
|
||||
}
|
||||
|
||||
interface IExtensionHostConnectionResult {
|
||||
protocol: PersistentProtocol;
|
||||
debugPort?: number;
|
||||
}
|
||||
|
||||
async function doConnectRemoteAgentExtensionHost(options: ISimpleConnectionOptions, startArguments: IRemoteExtensionHostStartParams): Promise<IExtensionHostConnectionResult> {
|
||||
const protocol = await connectToRemoteExtensionHostAgent(options, ConnectionType.ExtensionHost, startArguments);
|
||||
return new Promise<IExtensionHostConnectionResult>((c, e) => {
|
||||
const registration = protocol.onControlMessage(raw => {
|
||||
registration.dispose();
|
||||
const msg = JSON.parse(raw.toString());
|
||||
const error = getErrorFromMessage(msg);
|
||||
if (error) {
|
||||
return e(error);
|
||||
}
|
||||
const debugPort = msg && msg.debugPort;
|
||||
if (options.reconnectionProtocol) {
|
||||
options.reconnectionProtocol.endAcceptReconnection();
|
||||
}
|
||||
c({ protocol, debugPort });
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
export interface ITunnelConnectionStartParams {
|
||||
port: number;
|
||||
}
|
||||
|
||||
async function doConnectRemoteAgentTunnel(options: ISimpleConnectionOptions, startParams: ITunnelConnectionStartParams): Promise<PersistentProtocol> {
|
||||
const protocol = await connectToRemoteExtensionHostAgent(options, ConnectionType.Tunnel, startParams);
|
||||
return protocol;
|
||||
}
|
||||
|
||||
export interface IConnectionOptions {
|
||||
isBuilt: boolean;
|
||||
commit: string | undefined;
|
||||
webSocketFactory: IWebSocketFactory;
|
||||
addressProvider: IAddressProvider;
|
||||
}
|
||||
|
||||
async function resolveConnectionOptions(options: IConnectionOptions, reconnectionToken: string, reconnectionProtocol: PersistentProtocol | null): Promise<ISimpleConnectionOptions> {
|
||||
const { host, port } = await options.addressProvider.getAddress();
|
||||
return {
|
||||
isBuilt: options.isBuilt,
|
||||
commit: options.commit,
|
||||
host: host,
|
||||
port: port,
|
||||
reconnectionToken: reconnectionToken,
|
||||
reconnectionProtocol: reconnectionProtocol,
|
||||
webSocketFactory: options.webSocketFactory,
|
||||
};
|
||||
}
|
||||
|
||||
export interface IAddress {
|
||||
host: string;
|
||||
port: number;
|
||||
}
|
||||
|
||||
export interface IAddressProvider {
|
||||
getAddress(): Promise<IAddress>;
|
||||
}
|
||||
|
||||
export async function connectRemoteAgentManagement(options: IConnectionOptions, remoteAuthority: string, clientId: string): Promise<ManagementPersistentConnection> {
|
||||
const reconnectionToken = generateUuid();
|
||||
const simpleOptions = await resolveConnectionOptions(options, reconnectionToken, null);
|
||||
const { protocol } = await doConnectRemoteAgentManagement(simpleOptions);
|
||||
return new ManagementPersistentConnection(options, remoteAuthority, clientId, reconnectionToken, protocol);
|
||||
}
|
||||
|
||||
export async function connectRemoteAgentExtensionHost(options: IConnectionOptions, startArguments: IRemoteExtensionHostStartParams): Promise<ExtensionHostPersistentConnection> {
|
||||
const reconnectionToken = generateUuid();
|
||||
const simpleOptions = await resolveConnectionOptions(options, reconnectionToken, null);
|
||||
const { protocol, debugPort } = await doConnectRemoteAgentExtensionHost(simpleOptions, startArguments);
|
||||
return new ExtensionHostPersistentConnection(options, startArguments, reconnectionToken, protocol, debugPort);
|
||||
}
|
||||
|
||||
export async function connectRemoteAgentTunnel(options: IConnectionOptions, tunnelRemotePort: number): Promise<PersistentProtocol> {
|
||||
const simpleOptions = await resolveConnectionOptions(options, generateUuid(), null);
|
||||
const protocol = await doConnectRemoteAgentTunnel(simpleOptions, { port: tunnelRemotePort });
|
||||
return protocol;
|
||||
}
|
||||
|
||||
abstract class PersistentConnection extends Disposable {
|
||||
|
||||
protected readonly _options: IConnectionOptions;
|
||||
public readonly reconnectionToken: string;
|
||||
public readonly protocol: PersistentProtocol;
|
||||
|
||||
constructor(options: IConnectionOptions, reconnectionToken: string, protocol: PersistentProtocol) {
|
||||
super();
|
||||
this._options = options;
|
||||
this.reconnectionToken = reconnectionToken;
|
||||
this.protocol = protocol;
|
||||
}
|
||||
|
||||
protected abstract _reconnect(options: ISimpleConnectionOptions): Promise<void>;
|
||||
}
|
||||
|
||||
export class ManagementPersistentConnection extends PersistentConnection {
|
||||
|
||||
public readonly client: Client<RemoteAgentConnectionContext>;
|
||||
|
||||
constructor(options: IConnectionOptions, remoteAuthority: string, clientId: string, reconnectionToken: string, protocol: PersistentProtocol) {
|
||||
super(options, reconnectionToken, protocol);
|
||||
this.client = this._register(new Client<RemoteAgentConnectionContext>(protocol, {
|
||||
remoteAuthority: remoteAuthority,
|
||||
clientId: clientId
|
||||
}));
|
||||
}
|
||||
|
||||
protected async _reconnect(options: ISimpleConnectionOptions): Promise<void> {
|
||||
await doConnectRemoteAgentManagement(options);
|
||||
}
|
||||
}
|
||||
|
||||
export class ExtensionHostPersistentConnection extends PersistentConnection {
|
||||
|
||||
private readonly _startArguments: IRemoteExtensionHostStartParams;
|
||||
public readonly debugPort: number | undefined;
|
||||
|
||||
constructor(options: IConnectionOptions, startArguments: IRemoteExtensionHostStartParams, reconnectionToken: string, protocol: PersistentProtocol, debugPort: number | undefined) {
|
||||
super(options, reconnectionToken, protocol);
|
||||
this._startArguments = startArguments;
|
||||
this.debugPort = debugPort;
|
||||
}
|
||||
|
||||
protected async _reconnect(options: ISimpleConnectionOptions): Promise<void> {
|
||||
await doConnectRemoteAgentExtensionHost(options, this._startArguments);
|
||||
}
|
||||
}
|
||||
|
||||
function getErrorFromMessage(msg: any): Error | null {
|
||||
if (msg && msg.type === 'error') {
|
||||
const error = new Error(`Connection error: ${msg.reason}`);
|
||||
(<any>error).code = 'VSCODE_CONNECTION_ERROR';
|
||||
return error;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
12
src/vs/platform/remote/node/nodeWebSocketFactory.ts
Normal file
12
src/vs/platform/remote/node/nodeWebSocketFactory.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { IWebSocketFactory, IConnectCallback } from 'vs/platform/remote/common/remoteAgentConnection';
|
||||
|
||||
export const nodeWebSocketFactory = new class implements IWebSocketFactory {
|
||||
connect(host: string, port: number, query: string, callback: IConnectCallback): void {
|
||||
throw new Error(`Not implemented`);
|
||||
}
|
||||
};
|
||||
@@ -1,82 +0,0 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { Client, PersistentProtocol } from 'vs/base/parts/ipc/common/ipc.net';
|
||||
import { RemoteAgentConnectionContext } from 'vs/platform/remote/common/remoteAgentEnvironment';
|
||||
import { Disposable } from 'vs/base/common/lifecycle';
|
||||
|
||||
export interface IRemoteExtensionHostStartParams {
|
||||
language: string;
|
||||
debugId?: string;
|
||||
break?: boolean;
|
||||
port?: number | null;
|
||||
updatePort?: boolean;
|
||||
}
|
||||
|
||||
export interface IConnectionOptions {
|
||||
isBuilt: boolean;
|
||||
commit: string | undefined;
|
||||
addressProvider: IAddressProvider;
|
||||
}
|
||||
|
||||
export interface IAddress {
|
||||
host: string;
|
||||
port: number;
|
||||
}
|
||||
|
||||
export interface IAddressProvider {
|
||||
getAddress(): Promise<IAddress>;
|
||||
}
|
||||
|
||||
export async function connectRemoteAgentManagement(options: IConnectionOptions, remoteAuthority: string, clientId: string): Promise<ManagementPersistentConnection> {
|
||||
throw new Error(`Not implemented`);
|
||||
}
|
||||
|
||||
export async function connectRemoteAgentExtensionHost(options: IConnectionOptions, startArguments: IRemoteExtensionHostStartParams): Promise<ExtensionHostPersistentConnection> {
|
||||
throw new Error(`Not implemented`);
|
||||
}
|
||||
|
||||
export async function createRemoteTunnel(options: IConnectionOptions, tunnelRemotePort: number): Promise<RemoteTunnel> {
|
||||
throw new Error(`Not implemented`);
|
||||
}
|
||||
|
||||
export class RemoteTunnel extends Disposable {
|
||||
}
|
||||
|
||||
abstract class PersistentConnection extends Disposable {
|
||||
|
||||
public readonly reconnectionToken: string;
|
||||
public readonly protocol: PersistentProtocol;
|
||||
|
||||
constructor(reconnectionToken: string, protocol: PersistentProtocol) {
|
||||
super();
|
||||
this.reconnectionToken = reconnectionToken;
|
||||
this.protocol = protocol;
|
||||
}
|
||||
}
|
||||
|
||||
export class ManagementPersistentConnection extends PersistentConnection {
|
||||
|
||||
public readonly client: Client<RemoteAgentConnectionContext>;
|
||||
|
||||
constructor(remoteAuthority: string, host: string, port: number, clientId: string, isBuilt: boolean, reconnectionToken: string, protocol: PersistentProtocol) {
|
||||
super(reconnectionToken, protocol);
|
||||
|
||||
this.client = this._register(new Client<RemoteAgentConnectionContext>(protocol, {
|
||||
remoteAuthority: remoteAuthority,
|
||||
clientId: clientId
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
export class ExtensionHostPersistentConnection extends PersistentConnection {
|
||||
|
||||
public readonly debugPort: number | undefined;
|
||||
|
||||
constructor(host: string, port: number, startArguments: IRemoteExtensionHostStartParams, isBuilt: boolean, reconnectionToken: string, protocol: PersistentProtocol, debugPort: number | undefined) {
|
||||
super(reconnectionToken, protocol);
|
||||
this.debugPort = debugPort;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user