From 01fcf004a6cd41fa56e33fca224fd5fe49407406 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Wed, 4 Sep 2024 16:26:43 +0200 Subject: [PATCH] Use electron net directly in shared process (#227553) * Use electron net directly in shared process * add built file * introduce shared electron-node layer * remove electron-utility layer * fix (overlook): move back cli files to node --- .eslintplugin/code-import-patterns.ts | 22 ++++++++++++++----- .eslintrc.json | 18 +++++++++++++-- build/buildfile.js | 2 +- build/gulpfile.reh.js | 2 +- build/gulpfile.vscode.web.js | 2 +- build/lib/layersChecker.js | 16 ++++++++++++++ build/lib/layersChecker.ts | 18 +++++++++++++++ src/vs/code/electron-main/main.ts | 4 ++-- .../sharedProcess/contrib/codeCacheCleaner.ts | 0 .../sharedProcess/contrib/extensions.ts | 0 .../contrib/languagePackCachedDataCleaner.ts | 0 .../contrib/localizationsUpdater.ts | 0 .../sharedProcess/contrib/logsDataCleaner.ts | 0 .../contrib/storageDataCleaner.ts | 0 .../contrib/userDataProfilesCleaner.ts | 0 .../sharedProcess/sharedProcessMain.ts | 4 ++-- .../requestService.ts} | 2 +- .../electron-main/sharedProcess.ts | 2 +- test/unit/browser/index.amd.js | 2 +- test/unit/browser/index.js | 2 +- test/unit/node/index.amd.js | 2 +- test/unit/node/index.mjs | 2 +- 22 files changed, 79 insertions(+), 21 deletions(-) rename src/vs/code/{node => electron-node}/sharedProcess/contrib/codeCacheCleaner.ts (100%) rename src/vs/code/{node => electron-node}/sharedProcess/contrib/extensions.ts (100%) rename src/vs/code/{node => electron-node}/sharedProcess/contrib/languagePackCachedDataCleaner.ts (100%) rename src/vs/code/{node => electron-node}/sharedProcess/contrib/localizationsUpdater.ts (100%) rename src/vs/code/{node => electron-node}/sharedProcess/contrib/logsDataCleaner.ts (100%) rename src/vs/code/{node => electron-node}/sharedProcess/contrib/storageDataCleaner.ts (100%) rename src/vs/code/{node => electron-node}/sharedProcess/contrib/userDataProfilesCleaner.ts (100%) rename src/vs/code/{node => electron-node}/sharedProcess/sharedProcessMain.ts (99%) rename src/vs/platform/request/{electron-main/requestMainService.ts => electron-node/requestService.ts} (94%) diff --git a/.eslintplugin/code-import-patterns.ts b/.eslintplugin/code-import-patterns.ts index 932f71d1581..a3077654f09 100644 --- a/.eslintplugin/code-import-patterns.ts +++ b/.eslintplugin/code-import-patterns.ts @@ -12,19 +12,19 @@ import { createImportRuleListener } from './utils'; const REPO_ROOT = path.normalize(path.join(__dirname, '../')); interface ConditionalPattern { - when?: 'hasBrowser' | 'hasNode' | 'test'; + when?: 'hasBrowser' | 'hasNode' | 'hasElectron' | 'test'; pattern: string; } interface RawImportPatternsConfig { target: string; - layer?: 'common' | 'worker' | 'browser' | 'electron-sandbox' | 'node' | 'electron-main'; + layer?: 'common' | 'worker' | 'browser' | 'electron-sandbox' | 'node' | 'electron-node' | 'electron-main'; test?: boolean; restrictions: string | (string | ConditionalPattern)[]; } interface LayerAllowRule { - when: 'hasBrowser' | 'hasNode' | 'test'; + when: 'hasBrowser' | 'hasNode' | 'hasElectron' | 'test'; allow: string[]; } @@ -79,13 +79,14 @@ export = new class implements eslint.Rule.RuleModule { return this._optionsCache.get(options)!; } - type Layer = 'common' | 'worker' | 'browser' | 'electron-sandbox' | 'node' | 'electron-main'; + type Layer = 'common' | 'worker' | 'browser' | 'electron-sandbox' | 'node' | 'electron-node' | 'electron-main'; interface ILayerRule { layer: Layer; deps: string; isBrowser?: boolean; isNode?: boolean; + isElectron?: boolean; } function orSegment(variants: Layer[]): string { @@ -98,11 +99,13 @@ export = new class implements eslint.Rule.RuleModule { { layer: 'browser', deps: orSegment(['common', 'browser']), isBrowser: true }, { layer: 'electron-sandbox', deps: orSegment(['common', 'browser', 'electron-sandbox']), isBrowser: true }, { layer: 'node', deps: orSegment(['common', 'node']), isNode: true }, - { layer: 'electron-main', deps: orSegment(['common', 'node', 'electron-main']), isNode: true }, + { layer: 'electron-node', deps: orSegment(['common', 'node', 'electron-node']), isNode: true, isElectron: true }, + { layer: 'electron-main', deps: orSegment(['common', 'node', 'electron-node', 'electron-main']), isNode: true, isElectron: true }, ]; let browserAllow: string[] = []; let nodeAllow: string[] = []; + let electronAllow: string[] = []; let testAllow: string[] = []; for (const option of options) { if (isLayerAllowRule(option)) { @@ -110,6 +113,8 @@ export = new class implements eslint.Rule.RuleModule { browserAllow = option.allow.slice(0); } else if (option.when === 'hasNode') { nodeAllow = option.allow.slice(0); + } else if (option.when === 'hasElectron') { + electronAllow = option.allow.slice(0); } else if (option.when === 'test') { testAllow = option.allow.slice(0); } @@ -137,9 +142,13 @@ export = new class implements eslint.Rule.RuleModule { restrictions.push(...nodeAllow); } + if (layerRule.isElectron) { + restrictions.push(...electronAllow); + } + for (const rawRestriction of rawRestrictions) { let importPattern: string; - let when: 'hasBrowser' | 'hasNode' | 'test' | undefined = undefined; + let when: 'hasBrowser' | 'hasNode' | 'hasElectron' | 'test' | undefined = undefined; if (typeof rawRestriction === 'string') { importPattern = rawRestriction; } else { @@ -149,6 +158,7 @@ export = new class implements eslint.Rule.RuleModule { if (typeof when === 'undefined' || (when === 'hasBrowser' && layerRule.isBrowser) || (when === 'hasNode' && layerRule.isNode) + || (when === 'hasElectron' && layerRule.isElectron) ) { restrictions.push(importPattern.replace(/\/\~$/, `/${layerRule.deps}/**`)); testRestrictions.push(importPattern.replace(/\/\~$/, `/test/${layerRule.deps}/**`)); diff --git a/.eslintrc.json b/.eslintrc.json index 6e3d4615148..8196f8d828b 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -92,9 +92,14 @@ "common", "browser" ], - "electron-main": [ + "electron-node": [ "common", "node" + ], + "electron-main": [ + "common", + "node", + "electron-node" ] } ], @@ -630,6 +635,7 @@ { // imports that are allowed in all files of layers: // - node + // - electron-node // - electron-main "when": "hasNode", "allow": [ @@ -648,7 +654,6 @@ "cookie", "crypto", "dns", - "electron", "events", "fs", "fs/promises", @@ -687,6 +692,15 @@ "zlib" ] }, + { + // imports that are allowed in all files of layers: + // - electron-node + // - electron-main + "when": "hasElectron", + "allow": [ + "electron" + ] + }, { // imports that are allowed in all /test/ files "when": "test", diff --git a/build/buildfile.js b/build/buildfile.js index 14eeb9c1187..f82019860a7 100644 --- a/build/buildfile.js +++ b/build/buildfile.js @@ -109,7 +109,7 @@ exports.code = [ createModuleDescription('vs/code/electron-main/main'), createModuleDescription('vs/code/node/cli'), createModuleDescription('vs/code/node/cliProcessMain', ['vs/code/node/cli']), - createModuleDescription('vs/code/node/sharedProcess/sharedProcessMain'), + createModuleDescription('vs/code/electron-node/sharedProcess/sharedProcessMain'), createModuleDescription('vs/code/electron-sandbox/processExplorer/processExplorerMain') ]; diff --git a/build/gulpfile.reh.js b/build/gulpfile.reh.js index 3cb746fa8eb..bc4796ed988 100644 --- a/build/gulpfile.reh.js +++ b/build/gulpfile.reh.js @@ -78,7 +78,7 @@ const serverResourceIncludes = [ ]; const serverResourceExcludes = [ - '!out-build/vs/**/{electron-sandbox,electron-main}/**', + '!out-build/vs/**/{electron-sandbox,electron-main,electron-node}/**', '!out-build/vs/editor/standalone/**', '!out-build/vs/workbench/**/*-tb.png', '!**/test/**' diff --git a/build/gulpfile.vscode.web.js b/build/gulpfile.vscode.web.js index 3eb25153de1..6b6927ec8ac 100644 --- a/build/gulpfile.vscode.web.js +++ b/build/gulpfile.vscode.web.js @@ -87,7 +87,7 @@ const vscodeWebResources = [ ...vscodeWebResourceIncludes, // Excludes - '!out-build/vs/**/{node,electron-sandbox,electron-main}/**', + '!out-build/vs/**/{node,electron-sandbox,electron-main,electron-node}/**', '!out-build/vs/editor/standalone/**', '!out-build/vs/workbench/**/*-tb.png', '!out-build/vs/code/**/*-dev.html', diff --git a/build/lib/layersChecker.js b/build/lib/layersChecker.js index d734195421f..100884ee90c 100644 --- a/build/lib/layersChecker.js +++ b/build/lib/layersChecker.js @@ -235,6 +235,22 @@ const RULES = [ '@types/node' // no node.js ] }, + // Electron (node) + { + target: '**/vs/**/electron-node/**', + allowedTypes: [ + ...CORE_TYPES, + // --> types from electron.d.ts that duplicate from lib.dom.d.ts + 'Event', + 'Request' + ], + disallowedTypes: [ + 'ipcMain' // not allowed, use validatedIpcMain instead + ], + disallowedDefinitions: [ + 'lib.dom.d.ts' // no DOM + ] + }, // Electron (main) { target: '**/vs/**/electron-main/**', diff --git a/build/lib/layersChecker.ts b/build/lib/layersChecker.ts index 02d501d6478..8098daa8f48 100644 --- a/build/lib/layersChecker.ts +++ b/build/lib/layersChecker.ts @@ -257,6 +257,24 @@ const RULES: IRule[] = [ ] }, + // Electron (node) + { + target: '**/vs/**/electron-node/**', + allowedTypes: [ + ...CORE_TYPES, + + // --> types from electron.d.ts that duplicate from lib.dom.d.ts + 'Event', + 'Request' + ], + disallowedTypes: [ + 'ipcMain' // not allowed, use validatedIpcMain instead + ], + disallowedDefinitions: [ + 'lib.dom.d.ts' // no DOM + ] + }, + // Electron (main) { target: '**/vs/**/electron-main/**', diff --git a/src/vs/code/electron-main/main.ts b/src/vs/code/electron-main/main.ts index d445c0ce30e..5aa6fd7e0d1 100644 --- a/src/vs/code/electron-main/main.ts +++ b/src/vs/code/electron-main/main.ts @@ -53,7 +53,7 @@ import { ProtocolMainService } from '../../platform/protocol/electron-main/proto import { ITunnelService } from '../../platform/tunnel/common/tunnel.js'; import { TunnelService } from '../../platform/tunnel/node/tunnelService.js'; import { IRequestService } from '../../platform/request/common/request.js'; -import { RequestMainService } from '../../platform/request/electron-main/requestMainService.js'; +import { RequestService } from '../../platform/request/electron-node/requestService.js'; import { ISignService } from '../../platform/sign/common/sign.js'; import { SignService } from '../../platform/sign/node/signService.js'; import { IStateReadService, IStateService } from '../../platform/state/node/state.js'; @@ -211,7 +211,7 @@ class CodeMain { services.set(ILifecycleMainService, new SyncDescriptor(LifecycleMainService, undefined, false)); // Request - services.set(IRequestService, new SyncDescriptor(RequestMainService, undefined, true)); + services.set(IRequestService, new SyncDescriptor(RequestService, undefined, true)); // Themes services.set(IThemeMainService, new SyncDescriptor(ThemeMainService)); diff --git a/src/vs/code/node/sharedProcess/contrib/codeCacheCleaner.ts b/src/vs/code/electron-node/sharedProcess/contrib/codeCacheCleaner.ts similarity index 100% rename from src/vs/code/node/sharedProcess/contrib/codeCacheCleaner.ts rename to src/vs/code/electron-node/sharedProcess/contrib/codeCacheCleaner.ts diff --git a/src/vs/code/node/sharedProcess/contrib/extensions.ts b/src/vs/code/electron-node/sharedProcess/contrib/extensions.ts similarity index 100% rename from src/vs/code/node/sharedProcess/contrib/extensions.ts rename to src/vs/code/electron-node/sharedProcess/contrib/extensions.ts diff --git a/src/vs/code/node/sharedProcess/contrib/languagePackCachedDataCleaner.ts b/src/vs/code/electron-node/sharedProcess/contrib/languagePackCachedDataCleaner.ts similarity index 100% rename from src/vs/code/node/sharedProcess/contrib/languagePackCachedDataCleaner.ts rename to src/vs/code/electron-node/sharedProcess/contrib/languagePackCachedDataCleaner.ts diff --git a/src/vs/code/node/sharedProcess/contrib/localizationsUpdater.ts b/src/vs/code/electron-node/sharedProcess/contrib/localizationsUpdater.ts similarity index 100% rename from src/vs/code/node/sharedProcess/contrib/localizationsUpdater.ts rename to src/vs/code/electron-node/sharedProcess/contrib/localizationsUpdater.ts diff --git a/src/vs/code/node/sharedProcess/contrib/logsDataCleaner.ts b/src/vs/code/electron-node/sharedProcess/contrib/logsDataCleaner.ts similarity index 100% rename from src/vs/code/node/sharedProcess/contrib/logsDataCleaner.ts rename to src/vs/code/electron-node/sharedProcess/contrib/logsDataCleaner.ts diff --git a/src/vs/code/node/sharedProcess/contrib/storageDataCleaner.ts b/src/vs/code/electron-node/sharedProcess/contrib/storageDataCleaner.ts similarity index 100% rename from src/vs/code/node/sharedProcess/contrib/storageDataCleaner.ts rename to src/vs/code/electron-node/sharedProcess/contrib/storageDataCleaner.ts diff --git a/src/vs/code/node/sharedProcess/contrib/userDataProfilesCleaner.ts b/src/vs/code/electron-node/sharedProcess/contrib/userDataProfilesCleaner.ts similarity index 100% rename from src/vs/code/node/sharedProcess/contrib/userDataProfilesCleaner.ts rename to src/vs/code/electron-node/sharedProcess/contrib/userDataProfilesCleaner.ts diff --git a/src/vs/code/node/sharedProcess/sharedProcessMain.ts b/src/vs/code/electron-node/sharedProcess/sharedProcessMain.ts similarity index 99% rename from src/vs/code/node/sharedProcess/sharedProcessMain.ts rename to src/vs/code/electron-node/sharedProcess/sharedProcessMain.ts index 60c29b06bf3..0fd882974c1 100644 --- a/src/vs/code/node/sharedProcess/sharedProcessMain.ts +++ b/src/vs/code/electron-node/sharedProcess/sharedProcessMain.ts @@ -102,7 +102,6 @@ import { LogService } from '../../../platform/log/common/logService.js'; import { ISharedProcessLifecycleService, SharedProcessLifecycleService } from '../../../platform/lifecycle/node/sharedProcessLifecycleService.js'; import { RemoteTunnelService } from '../../../platform/remoteTunnel/node/remoteTunnelService.js'; import { ExtensionsProfileScannerService } from '../../../platform/extensionManagement/node/extensionsProfileScannerService.js'; -import { RequestChannelClient } from '../../../platform/request/common/requestIpc.js'; import { ExtensionRecommendationNotificationServiceChannelClient } from '../../../platform/extensionRecommendations/common/extensionRecommendationsIpc.js'; import { INativeHostService } from '../../../platform/native/common/native.js'; import { NativeHostService } from '../../../platform/native/common/nativeHostService.js'; @@ -118,6 +117,7 @@ import { SharedProcessRawConnection, SharedProcessLifecycle } from '../../../pla import { getOSReleaseInfo } from '../../../base/node/osReleaseInfo.js'; import { getDesktopEnvironment } from '../../../base/common/desktopEnvironmentInfo.js'; import { getCodeDisplayProtocol, getDisplayProtocol } from '../../../base/node/osDisplayProtocolInfo.js'; +import { RequestService } from '../../../platform/request/electron-node/requestService.js'; class SharedProcessMain extends Disposable implements IClientConnectionFilter { @@ -270,7 +270,7 @@ class SharedProcessMain extends Disposable implements IClientConnectionFilter { ]); // Request - const requestService = new RequestChannelClient(mainProcessService.getChannel('request')); + const requestService = new RequestService(configurationService, environmentService, logService, loggerService); services.set(IRequestService, requestService); // Checksum diff --git a/src/vs/platform/request/electron-main/requestMainService.ts b/src/vs/platform/request/electron-node/requestService.ts similarity index 94% rename from src/vs/platform/request/electron-main/requestMainService.ts rename to src/vs/platform/request/electron-node/requestService.ts index 7a0f37cc52c..f92a2450c3e 100644 --- a/src/vs/platform/request/electron-main/requestMainService.ts +++ b/src/vs/platform/request/electron-node/requestService.ts @@ -12,7 +12,7 @@ function getRawRequest(options: IRequestOptions): IRawRequestFunction { return net.request as any as IRawRequestFunction; } -export class RequestMainService extends NodeRequestService { +export class RequestService extends NodeRequestService { override request(options: IRequestOptions, token: CancellationToken): Promise { return super.request({ ...(options || {}), getRawRequest, isChromiumNetwork: true }, token); diff --git a/src/vs/platform/sharedProcess/electron-main/sharedProcess.ts b/src/vs/platform/sharedProcess/electron-main/sharedProcess.ts index 18571507dbf..52d7addfe56 100644 --- a/src/vs/platform/sharedProcess/electron-main/sharedProcess.ts +++ b/src/vs/platform/sharedProcess/electron-main/sharedProcess.ts @@ -169,7 +169,7 @@ export class SharedProcess extends Disposable { this.utilityProcess.start({ type: 'shared-process', - entryPoint: 'vs/code/node/sharedProcess/sharedProcessMain', + entryPoint: 'vs/code/electron-node/sharedProcess/sharedProcessMain', payload: this.createSharedProcessConfiguration(), execArgv }); diff --git a/test/unit/browser/index.amd.js b/test/unit/browser/index.amd.js index babe64ec762..54a1551d902 100644 --- a/test/unit/browser/index.amd.js +++ b/test/unit/browser/index.amd.js @@ -111,7 +111,7 @@ function ensureIsArray(a) { const testModules = (async function () { - const excludeGlob = '**/{node,electron-sandbox,electron-main}/**/*.test.js'; + const excludeGlob = '**/{node,electron-sandbox,electron-main,electron-node}/**/*.test.js'; let isDefaultModules = true; let promise; diff --git a/test/unit/browser/index.js b/test/unit/browser/index.js index b90e2c8a5de..ce24b569aff 100644 --- a/test/unit/browser/index.js +++ b/test/unit/browser/index.js @@ -114,7 +114,7 @@ function ensureIsArray(a) { const testModules = (async function () { - const excludeGlob = '**/{node,electron-sandbox,electron-main}/**/*.test.js'; + const excludeGlob = '**/{node,electron-sandbox,electron-main,electron-node}/**/*.test.js'; let isDefaultModules = true; let promise; diff --git a/test/unit/node/index.amd.js b/test/unit/node/index.amd.js index 3ad33597820..76fde4bce4d 100644 --- a/test/unit/node/index.amd.js +++ b/test/unit/node/index.amd.js @@ -56,7 +56,7 @@ Options: const TEST_GLOB = '**/test/**/*.test.js'; const excludeGlobs = [ - '**/{browser,electron-sandbox,electron-main}/**/*.test.js', + '**/{browser,electron-sandbox,electron-main,electron-node}/**/*.test.js', '**/vs/platform/environment/test/node/nativeModules.test.js', // native modules are compiled against Electron and this test would fail with node.js '**/vs/base/parts/storage/test/node/storage.test.js', // same as above, due to direct dependency to sqlite native module '**/vs/workbench/contrib/testing/test/**' // flaky (https://github.com/microsoft/vscode/issues/137853) diff --git a/test/unit/node/index.mjs b/test/unit/node/index.mjs index 210423c726f..55d4eb416ed 100644 --- a/test/unit/node/index.mjs +++ b/test/unit/node/index.mjs @@ -58,7 +58,7 @@ Options: const TEST_GLOB = '**/test/**/*.test.js'; const excludeGlobs = [ - '**/{browser,electron-sandbox,electron-main}/**/*.test.js', + '**/{browser,electron-sandbox,electron-main,electron-node}/**/*.test.js', '**/vs/platform/environment/test/node/nativeModules.test.js', // native modules are compiled against Electron and this test would fail with node.js '**/vs/base/parts/storage/test/node/storage.test.js', // same as above, due to direct dependency to sqlite native module '**/vs/workbench/contrib/testing/test/**' // flaky (https://github.com/microsoft/vscode/issues/137853)