"Fossies" - the Fresh Open Source Software Archive

Member "vscode-1.49.1/src/vs/workbench/services/remote/common/abstractRemoteAgentService.ts" (16 Sep 2020, 9056 Bytes) of package /linux/misc/vscode-1.49.1.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) TypeScript source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. See also the last Fossies "Diffs" side-by-side code changes report for "abstractRemoteAgentService.ts": 1.47.3_vs_1.48.0.

    1 /*---------------------------------------------------------------------------------------------
    2  *  Copyright (c) Microsoft Corporation. All rights reserved.
    3  *  Licensed under the MIT License. See License.txt in the project root for license information.
    4  *--------------------------------------------------------------------------------------------*/
    5 
    6 import * as nls from 'vs/nls';
    7 import { Disposable } from 'vs/base/common/lifecycle';
    8 import { IChannel, IServerChannel, getDelayedChannel, IPCLogger } from 'vs/base/parts/ipc/common/ipc';
    9 import { Client } from 'vs/base/parts/ipc/common/ipc.net';
   10 import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService';
   11 import { connectRemoteAgentManagement, IConnectionOptions, ISocketFactory, PersistenConnectionEvent } from 'vs/platform/remote/common/remoteAgentConnection';
   12 import { IRemoteAgentConnection, IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteAgentService';
   13 import { IRemoteAuthorityResolverService, RemoteAuthorityResolverError } from 'vs/platform/remote/common/remoteAuthorityResolver';
   14 import { LifecyclePhase } from 'vs/platform/lifecycle/common/lifecycle';
   15 import { RemoteAgentConnectionContext, IRemoteAgentEnvironment } from 'vs/platform/remote/common/remoteAgentEnvironment';
   16 import { IWorkbenchContribution, IWorkbenchContributionsRegistry, Extensions } from 'vs/workbench/common/contributions';
   17 import { Registry } from 'vs/platform/registry/common/platform';
   18 import { RemoteExtensionEnvironmentChannelClient } from 'vs/workbench/services/remote/common/remoteAgentEnvironmentChannel';
   19 import { INotificationService } from 'vs/platform/notification/common/notification';
   20 import { IDiagnosticInfoOptions, IDiagnosticInfo } from 'vs/platform/diagnostics/common/diagnostics';
   21 import { Emitter } from 'vs/base/common/event';
   22 import { ISignService } from 'vs/platform/sign/common/sign';
   23 import { ILogService } from 'vs/platform/log/common/log';
   24 import { ITelemetryData } from 'vs/platform/telemetry/common/telemetry';
   25 import { ExtensionIdentifier, IExtensionDescription } from 'vs/platform/extensions/common/extensions';
   26 import { IProductService } from 'vs/platform/product/common/productService';
   27 
   28 export abstract class AbstractRemoteAgentService extends Disposable implements IRemoteAgentService {
   29 
   30     declare readonly _serviceBrand: undefined;
   31 
   32     public readonly socketFactory: ISocketFactory;
   33     private readonly _connection: IRemoteAgentConnection | null;
   34     private _environment: Promise<IRemoteAgentEnvironment | null> | null;
   35 
   36     constructor(
   37         socketFactory: ISocketFactory,
   38         @IWorkbenchEnvironmentService protected readonly _environmentService: IWorkbenchEnvironmentService,
   39         @IProductService productService: IProductService,
   40         @IRemoteAuthorityResolverService private readonly _remoteAuthorityResolverService: IRemoteAuthorityResolverService,
   41         @ISignService signService: ISignService,
   42         @ILogService logService: ILogService
   43     ) {
   44         super();
   45         this.socketFactory = socketFactory;
   46         if (this._environmentService.configuration.remoteAuthority) {
   47             this._connection = this._register(new RemoteAgentConnection(this._environmentService.configuration.remoteAuthority, productService.commit, this.socketFactory, this._remoteAuthorityResolverService, signService, logService));
   48         } else {
   49             this._connection = null;
   50         }
   51         this._environment = null;
   52     }
   53 
   54     getConnection(): IRemoteAgentConnection | null {
   55         return this._connection;
   56     }
   57 
   58     getEnvironment(): Promise<IRemoteAgentEnvironment | null> {
   59         return this.getRawEnvironment().then(undefined, () => null);
   60     }
   61 
   62     getRawEnvironment(): Promise<IRemoteAgentEnvironment | null> {
   63         if (!this._environment) {
   64             this._environment = this._withChannel(
   65                 async (channel, connection) => {
   66                     const env = await RemoteExtensionEnvironmentChannelClient.getEnvironmentData(channel, connection.remoteAuthority);
   67                     this._remoteAuthorityResolverService._setAuthorityConnectionToken(connection.remoteAuthority, env.connectionToken);
   68                     return env;
   69                 },
   70                 null
   71             );
   72         }
   73         return this._environment;
   74     }
   75 
   76     scanExtensions(skipExtensions: ExtensionIdentifier[] = []): Promise<IExtensionDescription[]> {
   77         return this._withChannel(
   78             (channel, connection) => RemoteExtensionEnvironmentChannelClient.scanExtensions(channel, connection.remoteAuthority, this._environmentService.extensionDevelopmentLocationURI, skipExtensions),
   79             []
   80         ).then(undefined, () => []);
   81     }
   82 
   83     getDiagnosticInfo(options: IDiagnosticInfoOptions): Promise<IDiagnosticInfo | undefined> {
   84         return this._withChannel(
   85             channel => RemoteExtensionEnvironmentChannelClient.getDiagnosticInfo(channel, options),
   86             undefined
   87         );
   88     }
   89 
   90     disableTelemetry(): Promise<void> {
   91         return this._withChannel(
   92             channel => RemoteExtensionEnvironmentChannelClient.disableTelemetry(channel),
   93             undefined
   94         );
   95     }
   96 
   97     logTelemetry(eventName: string, data: ITelemetryData): Promise<void> {
   98         return this._withChannel(
   99             channel => RemoteExtensionEnvironmentChannelClient.logTelemetry(channel, eventName, data),
  100             undefined
  101         );
  102     }
  103 
  104     flushTelemetry(): Promise<void> {
  105         return this._withChannel(
  106             channel => RemoteExtensionEnvironmentChannelClient.flushTelemetry(channel),
  107             undefined
  108         );
  109     }
  110 
  111     private _withChannel<R>(callback: (channel: IChannel, connection: IRemoteAgentConnection) => Promise<R>, fallback: R): Promise<R> {
  112         const connection = this.getConnection();
  113         if (!connection) {
  114             return Promise.resolve(fallback);
  115         }
  116         return connection.withChannel('remoteextensionsenvironment', (channel) => callback(channel, connection));
  117     }
  118 }
  119 
  120 export class RemoteAgentConnection extends Disposable implements IRemoteAgentConnection {
  121 
  122     private readonly _onReconnecting = this._register(new Emitter<void>());
  123     public readonly onReconnecting = this._onReconnecting.event;
  124 
  125     private readonly _onDidStateChange = this._register(new Emitter<PersistenConnectionEvent>());
  126     public readonly onDidStateChange = this._onDidStateChange.event;
  127 
  128     readonly remoteAuthority: string;
  129     private _connection: Promise<Client<RemoteAgentConnectionContext>> | null;
  130 
  131     constructor(
  132         remoteAuthority: string,
  133         private readonly _commit: string | undefined,
  134         private readonly _socketFactory: ISocketFactory,
  135         private readonly _remoteAuthorityResolverService: IRemoteAuthorityResolverService,
  136         private readonly _signService: ISignService,
  137         private readonly _logService: ILogService
  138     ) {
  139         super();
  140         this.remoteAuthority = remoteAuthority;
  141         this._connection = null;
  142     }
  143 
  144     getChannel<T extends IChannel>(channelName: string): T {
  145         return <T>getDelayedChannel(this._getOrCreateConnection().then(c => c.getChannel(channelName)));
  146     }
  147 
  148     withChannel<T extends IChannel, R>(channelName: string, callback: (channel: T) => Promise<R>): Promise<R> {
  149         const channel = this.getChannel<T>(channelName);
  150         const result = callback(channel);
  151         return result;
  152     }
  153 
  154     registerChannel<T extends IServerChannel<RemoteAgentConnectionContext>>(channelName: string, channel: T): void {
  155         this._getOrCreateConnection().then(client => client.registerChannel(channelName, channel));
  156     }
  157 
  158     private _getOrCreateConnection(): Promise<Client<RemoteAgentConnectionContext>> {
  159         if (!this._connection) {
  160             this._connection = this._createConnection();
  161         }
  162         return this._connection;
  163     }
  164 
  165     private async _createConnection(): Promise<Client<RemoteAgentConnectionContext>> {
  166         let firstCall = true;
  167         const options: IConnectionOptions = {
  168             commit: this._commit,
  169             socketFactory: this._socketFactory,
  170             addressProvider: {
  171                 getAddress: async () => {
  172                     if (firstCall) {
  173                         firstCall = false;
  174                     } else {
  175                         this._onReconnecting.fire(undefined);
  176                     }
  177                     const { authority } = await this._remoteAuthorityResolverService.resolveAuthority(this.remoteAuthority);
  178                     return { host: authority.host, port: authority.port };
  179                 }
  180             },
  181             signService: this._signService,
  182             logService: this._logService,
  183             ipcLogger: false ? new IPCLogger(`Local \u2192 Remote`, `Remote \u2192 Local`) : null
  184         };
  185         const connection = this._register(await connectRemoteAgentManagement(options, this.remoteAuthority, `renderer`));
  186         this._register(connection.onDidStateChange(e => this._onDidStateChange.fire(e)));
  187         return connection.client;
  188     }
  189 }
  190 
  191 class RemoteConnectionFailureNotificationContribution implements IWorkbenchContribution {
  192 
  193     constructor(
  194         @IRemoteAgentService remoteAgentService: IRemoteAgentService,
  195         @INotificationService notificationService: INotificationService,
  196     ) {
  197         // Let's cover the case where connecting to fetch the remote extension info fails
  198         remoteAgentService.getRawEnvironment()
  199             .then(undefined, err => {
  200                 if (!RemoteAuthorityResolverError.isHandled(err)) {
  201                     notificationService.error(nls.localize('connectionError', "Failed to connect to the remote extension host server (Error: {0})", err ? err.message : ''));
  202                 }
  203             });
  204     }
  205 
  206 }
  207 
  208 const workbenchRegistry = Registry.as<IWorkbenchContributionsRegistry>(Extensions.Workbench);
  209 workbenchRegistry.registerWorkbenchContribution(RemoteConnectionFailureNotificationContribution, LifecyclePhase.Ready);