|
|
|
|
@@ -4,8 +4,6 @@
|
|
|
|
|
*--------------------------------------------------------------------------------------------*/
|
|
|
|
|
|
|
|
|
|
import { ipcRenderer } from 'electron';
|
|
|
|
|
import * as fs from 'fs';
|
|
|
|
|
import { gracefulify } from 'graceful-fs';
|
|
|
|
|
import { hostname, release } from 'os';
|
|
|
|
|
import { toErrorMessage } from 'vs/base/common/errorMessage';
|
|
|
|
|
import { onUnexpectedError, setUnexpectedErrorHandler } from 'vs/base/common/errors';
|
|
|
|
|
@@ -65,7 +63,7 @@ import { ICustomEndpointTelemetryService, ITelemetryService } from 'vs/platform/
|
|
|
|
|
import { TelemetryAppenderChannel } from 'vs/platform/telemetry/common/telemetryIpc';
|
|
|
|
|
import { TelemetryLogAppender } from 'vs/platform/telemetry/common/telemetryLogAppender';
|
|
|
|
|
import { TelemetryService } from 'vs/platform/telemetry/common/telemetryService';
|
|
|
|
|
import { combinedAppender, ITelemetryAppender, NullAppender, NullTelemetryService } from 'vs/platform/telemetry/common/telemetryUtils';
|
|
|
|
|
import { supportsTelemetry, ITelemetryAppender, NullAppender, NullTelemetryService } from 'vs/platform/telemetry/common/telemetryUtils';
|
|
|
|
|
import { AppInsightsAppender } from 'vs/platform/telemetry/node/appInsightsAppender';
|
|
|
|
|
import { CustomEndpointTelemetryService } from 'vs/platform/telemetry/node/customEndpointTelemetryService';
|
|
|
|
|
import { LocalReconnectConstants, TerminalIpcChannels, TerminalSettingId } from 'vs/platform/terminal/common/terminal';
|
|
|
|
|
@@ -86,26 +84,51 @@ import { UserDataSyncChannel } from 'vs/platform/userDataSync/common/userDataSyn
|
|
|
|
|
import { UserDataSyncStoreManagementService, UserDataSyncStoreService } from 'vs/platform/userDataSync/common/userDataSyncStoreService';
|
|
|
|
|
import { UserDataAutoSyncService } from 'vs/platform/userDataSync/electron-sandbox/userDataAutoSyncService';
|
|
|
|
|
import { ActiveWindowManager } from 'vs/platform/windows/node/windowTracker';
|
|
|
|
|
import { IExtensionHostStarter, ipcExtensionHostStarterChannelName } from 'vs/platform/extensions/common/extensionHostStarter';
|
|
|
|
|
import { ExtensionHostStarter } from 'vs/platform/extensions/node/extensionHostStarter';
|
|
|
|
|
import { ISignService } from 'vs/platform/sign/common/sign';
|
|
|
|
|
import { SignService } from 'vs/platform/sign/node/signService';
|
|
|
|
|
import { ISharedTunnelsService } from 'vs/platform/remote/common/tunnel';
|
|
|
|
|
import { SharedTunnelsService } from 'vs/platform/remote/node/tunnelService';
|
|
|
|
|
import { ipcSharedProcessTunnelChannelName, ISharedProcessTunnelService } from 'vs/platform/remote/common/sharedProcessTunnelService';
|
|
|
|
|
import { SharedProcessTunnelService } from 'vs/platform/remote/node/sharedProcessTunnelService';
|
|
|
|
|
import { ipcSharedProcessWorkerChannelName, ISharedProcessWorkerConfiguration, ISharedProcessWorkerService } from 'vs/platform/sharedProcess/common/sharedProcessWorkerService';
|
|
|
|
|
import { SharedProcessWorkerService } from 'vs/platform/sharedProcess/electron-browser/sharedProcessWorkerService';
|
|
|
|
|
import { IUserConfigurationFileService, UserConfigurationFileServiceId } from 'vs/platform/configuration/common/userConfigurationFileService';
|
|
|
|
|
|
|
|
|
|
class SharedProcessMain extends Disposable {
|
|
|
|
|
|
|
|
|
|
private server = this._register(new MessagePortServer());
|
|
|
|
|
|
|
|
|
|
private sharedProcessWorkerService: ISharedProcessWorkerService | undefined = undefined;
|
|
|
|
|
|
|
|
|
|
constructor(private configuration: ISharedProcessConfiguration) {
|
|
|
|
|
super();
|
|
|
|
|
|
|
|
|
|
// Enable gracefulFs
|
|
|
|
|
gracefulify(fs);
|
|
|
|
|
|
|
|
|
|
this.registerListeners();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private registerListeners(): void {
|
|
|
|
|
|
|
|
|
|
// Dispose on exit
|
|
|
|
|
// Shared process lifecycle
|
|
|
|
|
const onExit = () => this.dispose();
|
|
|
|
|
process.once('exit', onExit);
|
|
|
|
|
ipcRenderer.once('vscode:electron-main->shared-process=exit', onExit);
|
|
|
|
|
|
|
|
|
|
// Shared process worker lifecycle
|
|
|
|
|
//
|
|
|
|
|
// We dispose the listener when the shared process is
|
|
|
|
|
// disposed to avoid disposing workers when the entire
|
|
|
|
|
// application is shutting down anyways.
|
|
|
|
|
//
|
|
|
|
|
const eventName = 'vscode:electron-main->shared-process=disposeWorker';
|
|
|
|
|
const onDisposeWorker = (event: unknown, configuration: ISharedProcessWorkerConfiguration) => this.onDisposeWorker(configuration);
|
|
|
|
|
ipcRenderer.on(eventName, onDisposeWorker);
|
|
|
|
|
this._register(toDisposable(() => ipcRenderer.removeListener(eventName, onDisposeWorker)));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private onDisposeWorker(configuration: ISharedProcessWorkerConfiguration): void {
|
|
|
|
|
this.sharedProcessWorkerService?.disposeWorker(configuration);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async open(): Promise<void> {
|
|
|
|
|
@@ -170,6 +193,10 @@ class SharedProcessMain extends Disposable {
|
|
|
|
|
const logService = this._register(new FollowerLogService(logLevelClient, multiplexLogger));
|
|
|
|
|
services.set(ILogService, logService);
|
|
|
|
|
|
|
|
|
|
// Worker
|
|
|
|
|
this.sharedProcessWorkerService = new SharedProcessWorkerService(logService);
|
|
|
|
|
services.set(ISharedProcessWorkerService, this.sharedProcessWorkerService);
|
|
|
|
|
|
|
|
|
|
// Files
|
|
|
|
|
const fileService = this._register(new FileService(logService));
|
|
|
|
|
services.set(IFileService, fileService);
|
|
|
|
|
@@ -181,15 +208,20 @@ class SharedProcessMain extends Disposable {
|
|
|
|
|
const configurationService = this._register(new ConfigurationService(environmentService.settingsResource, fileService));
|
|
|
|
|
services.set(IConfigurationService, configurationService);
|
|
|
|
|
|
|
|
|
|
await configurationService.initialize();
|
|
|
|
|
|
|
|
|
|
// Storage (global access only)
|
|
|
|
|
const storageService = new NativeStorageService(undefined, mainProcessService, environmentService);
|
|
|
|
|
services.set(IStorageService, storageService);
|
|
|
|
|
|
|
|
|
|
await storageService.initialize();
|
|
|
|
|
this._register(toDisposable(() => storageService.flush()));
|
|
|
|
|
|
|
|
|
|
// Initialize config & storage in parallel
|
|
|
|
|
await Promise.all([
|
|
|
|
|
configurationService.initialize(),
|
|
|
|
|
storageService.initialize()
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
// User Configuration File
|
|
|
|
|
services.set(IUserConfigurationFileService, ProxyChannel.toService<IUserConfigurationFileService>(mainProcessService.getChannel(UserConfigurationFileServiceId)));
|
|
|
|
|
|
|
|
|
|
// Request
|
|
|
|
|
services.set(IRequestService, new SyncDescriptor(RequestService));
|
|
|
|
|
|
|
|
|
|
@@ -210,31 +242,32 @@ class SharedProcessMain extends Disposable {
|
|
|
|
|
|
|
|
|
|
// Telemetry
|
|
|
|
|
let telemetryService: ITelemetryService;
|
|
|
|
|
let telemetryAppender: ITelemetryAppender;
|
|
|
|
|
if (!environmentService.isExtensionDevelopment && !environmentService.disableTelemetry && productService.enableTelemetry) {
|
|
|
|
|
telemetryAppender = new TelemetryLogAppender(loggerService, environmentService);
|
|
|
|
|
|
|
|
|
|
const { appRoot, extensionsPath, isBuilt, installSourcePath } = environmentService;
|
|
|
|
|
const appenders: ITelemetryAppender[] = [];
|
|
|
|
|
if (supportsTelemetry(productService, environmentService)) {
|
|
|
|
|
const logAppender = new TelemetryLogAppender(loggerService, environmentService);
|
|
|
|
|
appenders.push(logAppender);
|
|
|
|
|
const { appRoot, extensionsPath, installSourcePath } = environmentService;
|
|
|
|
|
|
|
|
|
|
// Application Insights
|
|
|
|
|
if (productService.aiConfig && productService.aiConfig.asimovKey && isBuilt) {
|
|
|
|
|
if (productService.aiConfig && productService.aiConfig.asimovKey) {
|
|
|
|
|
const appInsightsAppender = new AppInsightsAppender('adsworkbench', null, productService.aiConfig.asimovKey); // {{SQL CARBON EDIT}} Use our own event prefix
|
|
|
|
|
this._register(toDisposable(() => appInsightsAppender.flush())); // Ensure the AI appender is disposed so that it flushes remaining data
|
|
|
|
|
telemetryAppender = combinedAppender(appInsightsAppender, telemetryAppender);
|
|
|
|
|
appenders.push(appInsightsAppender);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
telemetryService = new TelemetryService({
|
|
|
|
|
appender: telemetryAppender,
|
|
|
|
|
appenders,
|
|
|
|
|
commonProperties: resolveCommonProperties(fileService, release(), hostname(), process.arch, productService.commit, productService.version, this.configuration.machineId, productService.msftInternalDomains, installSourcePath),
|
|
|
|
|
sendErrorTelemetry: true,
|
|
|
|
|
piiPaths: [appRoot, extensionsPath]
|
|
|
|
|
}, configurationService);
|
|
|
|
|
} else {
|
|
|
|
|
telemetryService = NullTelemetryService;
|
|
|
|
|
telemetryAppender = NullAppender;
|
|
|
|
|
const nullAppender = NullAppender;
|
|
|
|
|
appenders.push(nullAppender);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
this.server.registerChannel('telemetryAppender', new TelemetryAppenderChannel(telemetryAppender));
|
|
|
|
|
this.server.registerChannel('telemetryAppender', new TelemetryAppenderChannel(appenders));
|
|
|
|
|
services.set(ITelemetryService, telemetryService);
|
|
|
|
|
|
|
|
|
|
// Custom Endpoint Telemetry
|
|
|
|
|
@@ -271,22 +304,30 @@ class SharedProcessMain extends Disposable {
|
|
|
|
|
services.set(IUserDataSyncResourceEnablementService, new SyncDescriptor(UserDataSyncResourceEnablementService));
|
|
|
|
|
services.set(IUserDataSyncService, new SyncDescriptor(UserDataSyncService));
|
|
|
|
|
|
|
|
|
|
// Terminal
|
|
|
|
|
services.set(
|
|
|
|
|
ILocalPtyService,
|
|
|
|
|
this._register(
|
|
|
|
|
new PtyHostService({
|
|
|
|
|
graceTime: LocalReconnectConstants.GraceTime,
|
|
|
|
|
shortGraceTime: LocalReconnectConstants.ShortGraceTime,
|
|
|
|
|
scrollback: configurationService.getValue<number>(TerminalSettingId.PersistentSessionScrollback) ?? 100,
|
|
|
|
|
useExperimentalSerialization: configurationService.getValue<boolean>(TerminalSettingId.PersistentSessionExperimentalSerializer) ?? true,
|
|
|
|
|
},
|
|
|
|
|
configurationService,
|
|
|
|
|
logService,
|
|
|
|
|
telemetryService
|
|
|
|
|
)
|
|
|
|
|
)
|
|
|
|
|
const ptyHostService = new PtyHostService({
|
|
|
|
|
graceTime: LocalReconnectConstants.GraceTime,
|
|
|
|
|
shortGraceTime: LocalReconnectConstants.ShortGraceTime,
|
|
|
|
|
scrollback: configurationService.getValue<number>(TerminalSettingId.PersistentSessionScrollback) ?? 100
|
|
|
|
|
},
|
|
|
|
|
configurationService,
|
|
|
|
|
environmentService,
|
|
|
|
|
logService,
|
|
|
|
|
telemetryService
|
|
|
|
|
);
|
|
|
|
|
await ptyHostService.initialize();
|
|
|
|
|
|
|
|
|
|
// Terminal
|
|
|
|
|
services.set(ILocalPtyService, this._register(ptyHostService));
|
|
|
|
|
|
|
|
|
|
// Extension Host
|
|
|
|
|
services.set(IExtensionHostStarter, this._register(new ExtensionHostStarter(logService)));
|
|
|
|
|
|
|
|
|
|
// Signing
|
|
|
|
|
services.set(ISignService, new SyncDescriptor(SignService));
|
|
|
|
|
|
|
|
|
|
// Tunnel
|
|
|
|
|
services.set(ISharedTunnelsService, new SyncDescriptor(SharedTunnelsService));
|
|
|
|
|
services.set(ISharedProcessTunnelService, new SyncDescriptor(SharedProcessTunnelService));
|
|
|
|
|
|
|
|
|
|
return new InstantiationService(services);
|
|
|
|
|
}
|
|
|
|
|
@@ -338,6 +379,18 @@ class SharedProcessMain extends Disposable {
|
|
|
|
|
const localPtyService = accessor.get(ILocalPtyService);
|
|
|
|
|
const localPtyChannel = ProxyChannel.fromService(localPtyService);
|
|
|
|
|
this.server.registerChannel(TerminalIpcChannels.LocalPty, localPtyChannel);
|
|
|
|
|
|
|
|
|
|
// Extension Host
|
|
|
|
|
const extensionHostStarterChannel = ProxyChannel.fromService(accessor.get(IExtensionHostStarter));
|
|
|
|
|
this.server.registerChannel(ipcExtensionHostStarterChannelName, extensionHostStarterChannel);
|
|
|
|
|
|
|
|
|
|
// Tunnel
|
|
|
|
|
const sharedProcessTunnelChannel = ProxyChannel.fromService(accessor.get(ISharedProcessTunnelService));
|
|
|
|
|
this.server.registerChannel(ipcSharedProcessTunnelChannelName, sharedProcessTunnelChannel);
|
|
|
|
|
|
|
|
|
|
// Worker
|
|
|
|
|
const sharedProcessWorkerChannel = ProxyChannel.fromService(accessor.get(ISharedProcessWorkerService));
|
|
|
|
|
this.server.registerChannel(ipcSharedProcessWorkerChannelName, sharedProcessWorkerChannel);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private registerErrorHandler(logService: ILogService): void {
|
|
|
|
|
|