diff --git a/src/vs/code/electron-browser/sharedProcess/sharedProcess.js b/src/vs/code/electron-browser/sharedProcess/sharedProcess.js index d3315d0a073..2bb0a0bb730 100644 --- a/src/vs/code/electron-browser/sharedProcess/sharedProcess.js +++ b/src/vs/code/electron-browser/sharedProcess/sharedProcess.js @@ -15,10 +15,7 @@ // Load shared process into window bootstrapWindow.load(['vs/code/electron-browser/sharedProcess/sharedProcessMain'], function (sharedProcess, configuration) { - return sharedProcess.main({ - machineId: configuration.machineId, - windowId: configuration.windowId - }); + return sharedProcess.main(configuration); }); diff --git a/src/vs/code/electron-browser/sharedProcess/sharedProcessMain.ts b/src/vs/code/electron-browser/sharedProcess/sharedProcessMain.ts index 2846ac152b5..a65090daa1d 100644 --- a/src/vs/code/electron-browser/sharedProcess/sharedProcessMain.ts +++ b/src/vs/code/electron-browser/sharedProcess/sharedProcessMain.ts @@ -12,7 +12,6 @@ import { ServiceCollection } from 'vs/platform/instantiation/common/serviceColle import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors'; import { InstantiationService } from 'vs/platform/instantiation/common/instantiationService'; import { IEnvironmentService, INativeEnvironmentService } from 'vs/platform/environment/common/environment'; -import { NativeParsedArgs } from 'vs/platform/environment/common/argv'; import { NativeEnvironmentService } from 'vs/platform/environment/node/environmentService'; import { ExtensionManagementChannel, ExtensionTipsChannel } from 'vs/platform/extensionManagement/common/extensionManagementIpc'; import { IExtensionManagementService, IExtensionGalleryService, IGlobalExtensionEnablementService, IExtensionTipsService } from 'vs/platform/extensionManagement/common/extensionManagement'; @@ -29,7 +28,7 @@ import { TelemetryAppenderChannel } from 'vs/platform/telemetry/node/telemetryIp import { TelemetryService } from 'vs/platform/telemetry/common/telemetryService'; import { AppInsightsAppender } from 'vs/platform/telemetry/node/appInsightsAppender'; import { ipcRenderer } from 'vs/base/parts/sandbox/electron-sandbox/globals'; -import { ILogService, LogLevel, ILoggerService } from 'vs/platform/log/common/log'; +import { ILogService, ILoggerService, MultiplexLogService, ConsoleLogService } from 'vs/platform/log/common/log'; import { LoggerChannelClient, FollowerLogService } from 'vs/platform/log/common/logIpc'; import { LocalizationsService } from 'vs/platform/localizations/node/localizations'; import { ILocalizationsService } from 'vs/platform/localizations/common/localizations'; @@ -73,19 +72,7 @@ import { UserDataAutoSyncEnablementService } from 'vs/platform/userDataSync/comm import { IgnoredExtensionsManagementService, IIgnoredExtensionsManagementService } from 'vs/platform/userDataSync/common/ignoredExtensions'; import { ExtensionsStorageSyncService, IExtensionsStorageSyncService } from 'vs/platform/userDataSync/common/extensionsStorageSync'; import { IInstantiationService, ServicesAccessor } from 'vs/platform/instantiation/common/instantiation'; - -interface ISharedProcessConfiguration { - readonly machineId: string; - readonly windowId: number; -} - -interface ISharedProcessInitData { - sharedIPCHandle: string; - args: NativeParsedArgs; - logLevel: LogLevel; - nodeCachedDataDir?: string; - backupWorkspacesPath: string; -} +import { ISharedProcessConfiguration } from 'vs/platform/sharedProcess/node/sharedProcess'; class MainProcessService implements IMainProcessService { @@ -107,7 +94,7 @@ class MainProcessService implements IMainProcessService { class SharedProcessMain extends Disposable { - constructor(private server: NodeIPCServer, private initData: ISharedProcessInitData, private configuration: ISharedProcessConfiguration) { + constructor(private server: NodeIPCServer, private configuration: ISharedProcessConfiguration) { super(); this._register(this.server); @@ -134,7 +121,7 @@ class SharedProcessMain extends Disposable { instantiationService.invokeFunction(accessor => { // Log info - accessor.get(ILogService).info('sharedProcess main', JSON.stringify(this.configuration)); + accessor.get(ILogService).trace('sharedProcess configuration', JSON.stringify(this.configuration)); // Channels this.initChannels(accessor); @@ -149,9 +136,9 @@ class SharedProcessMain extends Disposable { // Instantiate Clean-up helpers this._register(combinedDisposable( - new NodeCachedDataCleaner(this.initData.nodeCachedDataDir), + new NodeCachedDataCleaner(this.configuration.nodeCachedDataDir), instantiationService.createInstance(LanguagePackCachedDataCleaner), - instantiationService.createInstance(StorageDataCleaner, this.initData.backupWorkspacesPath), + instantiationService.createInstance(StorageDataCleaner, this.configuration.backupWorkspacesPath), instantiationService.createInstance(LogsDataCleaner) )); } @@ -160,14 +147,18 @@ class SharedProcessMain extends Disposable { const services = new ServiceCollection(); // Environment - const environmentService = new NativeEnvironmentService(this.initData.args); + const environmentService = new NativeEnvironmentService(this.configuration.args); services.set(IEnvironmentService, environmentService); services.set(INativeEnvironmentService, environmentService); // Log const mainRouter = new StaticRouter(ctx => ctx === 'main'); const loggerClient = new LoggerChannelClient(this.server.getChannel('logger', mainRouter)); - const logService = this._register(new FollowerLogService(loggerClient, new SpdLogService('sharedprocess', environmentService.logsPath, this.initData.logLevel))); + const multiplexLogger = this._register(new MultiplexLogService([ + this._register(new ConsoleLogService(this.configuration.logLevel)), + this._register(new SpdLogService('sharedprocess', environmentService.logsPath, this.configuration.logLevel)) + ])); + const logService = this._register(new FollowerLogService(loggerClient, multiplexLogger)); services.set(ILogService, logService); // Main Process @@ -323,7 +314,7 @@ class SharedProcessMain extends Disposable { } } -function setupIPC(hook: string): Promise { +function setupNodeIPC(hook: string): Promise { function setup(retry: boolean): Promise { return nodeIPCServe(hook).then(null, err => { if (!retry || isWindows || err.code !== 'EADDRINUSE') { @@ -359,20 +350,12 @@ function setupIPC(hook: string): Promise { export async function main(configuration: ISharedProcessConfiguration): Promise { - // receive payload from electron-main to start things - const initData = await new Promise(resolve => { - ipcRenderer.once('vscode:electron-main->shared-process=payload', (event: unknown, r: ISharedProcessInitData) => resolve(r)); - - // tell electron-main we are ready to receive payload - ipcRenderer.send('vscode:shared-process->electron-main=ready-for-payload'); - }); - // await IPC connection and signal this back to electron-main - const server = await setupIPC(initData.sharedIPCHandle); + const server = await setupNodeIPC(configuration.sharedIPCHandle); ipcRenderer.send('vscode:shared-process->electron-main=ipc-ready'); // await initialization and signal this back to electron-main - const sharedProcess = new SharedProcessMain(server, initData, configuration); + const sharedProcess = new SharedProcessMain(server, configuration); await sharedProcess.open(); ipcRenderer.send('vscode:shared-process->electron-main=init-done'); } diff --git a/src/vs/code/electron-main/sharedProcess.ts b/src/vs/code/electron-main/sharedProcess.ts index a065048ca5f..8548e85e92b 100644 --- a/src/vs/code/electron-main/sharedProcess.ts +++ b/src/vs/code/electron-main/sharedProcess.ts @@ -5,16 +5,16 @@ import { memoize } from 'vs/base/common/decorators'; import { IEnvironmentMainService } from 'vs/platform/environment/electron-main/environmentMainService'; -import { BrowserWindow, ipcMain, WebContents, Event as ElectronEvent } from 'electron'; +import { BrowserWindow, ipcMain, Event } from 'electron'; import { ISharedProcess } from 'vs/platform/ipc/electron-main/sharedProcessMainService'; import { Barrier } from 'vs/base/common/async'; import { ILogService } from 'vs/platform/log/common/log'; import { ILifecycleMainService } from 'vs/platform/lifecycle/electron-main/lifecycleMainService'; import { IThemeMainService } from 'vs/platform/theme/electron-main/themeMainService'; import { toDisposable, DisposableStore } from 'vs/base/common/lifecycle'; -import { Event } from 'vs/base/common/event'; import { FileAccess } from 'vs/base/common/network'; import { browserCodeLoadingCacheStrategy } from 'vs/base/common/platform'; +import { ISharedProcessConfiguration } from 'vs/platform/sharedProcess/node/sharedProcess'; export class SharedProcess implements ISharedProcess { @@ -54,12 +54,16 @@ export class SharedProcess implements ISharedProcess { } }); - const config = { - appRoot: this.environmentService.appRoot, + const config: ISharedProcessConfiguration = { machineId: this.machineId, + windowId: this.window.id, + appRoot: this.environmentService.appRoot, nodeCachedDataDir: this.environmentService.nodeCachedDataDir, + backupWorkspacesPath: this.environmentService.backupWorkspacesPath, userEnv: this.userEnv, - windowId: this.window.id + sharedIPCHandle: this.environmentService.sharedIPCHandle, + args: this.environmentService.args, + logLevel: this.logService.getLevel() }; this.window.loadURL(FileAccess @@ -69,7 +73,7 @@ export class SharedProcess implements ISharedProcess { ); // Prevent the window from dying - const onClose = (e: ElectronEvent) => { + const onClose = (e: Event) => { this.logService.trace('SharedProcess#close prevented'); // We never allow to close the shared process unless we get explicitly disposed() @@ -114,22 +118,11 @@ export class SharedProcess implements ISharedProcess { return new Promise(resolve => { - // send payload once shared process is ready to receive it - disposables.add(Event.once(Event.fromNodeEventEmitter(ipcMain, 'vscode:shared-process->electron-main=ready-for-payload', ({ sender }: { sender: WebContents }) => sender))(sender => { - sender.send('vscode:electron-main->shared-process=payload', { - sharedIPCHandle: this.environmentService.sharedIPCHandle, - args: this.environmentService.args, - logLevel: this.logService.getLevel(), - backupWorkspacesPath: this.environmentService.backupWorkspacesPath, - nodeCachedDataDir: this.environmentService.nodeCachedDataDir - }); + // signal exit to shared process when we get disposed + disposables.add(toDisposable(() => this.window?.webContents.send('vscode:electron-main->shared-process=exit'))); - // signal exit to shared process when we get disposed - disposables.add(toDisposable(() => sender.send('vscode:electron-main->shared-process=exit'))); - - // complete IPC-ready promise when shared process signals this to us - ipcMain.once('vscode:shared-process->electron-main=ipc-ready', () => resolve(undefined)); - })); + // complete IPC-ready promise when shared process signals this to us + ipcMain.once('vscode:shared-process->electron-main=ipc-ready', () => resolve(undefined)); }); } diff --git a/src/vs/platform/sharedProcess/node/sharedProcess.ts b/src/vs/platform/sharedProcess/node/sharedProcess.ts new file mode 100644 index 00000000000..167e1bcbcba --- /dev/null +++ b/src/vs/platform/sharedProcess/node/sharedProcess.ts @@ -0,0 +1,25 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { NativeParsedArgs } from 'vs/platform/environment/common/argv'; +import { LogLevel } from 'vs/platform/log/common/log'; + +export interface ISharedProcessConfiguration { + readonly machineId: string; + readonly windowId: number; + + readonly appRoot: string; + + readonly userEnv: NodeJS.ProcessEnv; + + readonly sharedIPCHandle: string; + + readonly args: NativeParsedArgs; + + readonly logLevel: LogLevel; + + readonly nodeCachedDataDir?: string; + readonly backupWorkspacesPath: string; +} diff --git a/src/vs/workbench/services/log/electron-browser/logService.ts b/src/vs/workbench/services/log/electron-browser/logService.ts index c230f8920bf..7169b6cf7d1 100644 --- a/src/vs/workbench/services/log/electron-browser/logService.ts +++ b/src/vs/workbench/services/log/electron-browser/logService.ts @@ -39,7 +39,7 @@ export class NativeLogService extends DelegatedLogService { bufferSpdLogService = disposables.add(new BufferLogService(environmentService.configuration.logLevel)); loggers.push( disposables.add(new ConsoleLogService(environmentService.configuration.logLevel)), - bufferSpdLogService, + bufferSpdLogService ); }