UNPKG

@codingame/monaco-vscode-extensions-service-override

Version:

VSCode public API plugged on the monaco editor - extensions service-override

275 lines (272 loc) 15.5 kB
import { __decorate, __param } from 'vscode/external/tslib/tslib.es6.js'; import { Schemas } from 'vscode/vscode/vs/base/common/network'; import { IConfigurationService } from 'vscode/vscode/vs/platform/configuration/common/configuration.service'; import { ExtensionIdentifierMap } from 'vscode/vscode/vs/platform/extensions/common/extensions'; import { ILogService } from 'vscode/vscode/vs/platform/log/common/log.service'; import { IWorkbenchEnvironmentService } from 'vscode/vscode/vs/workbench/services/environment/common/environmentService.service'; import { determineExtensionHostKinds, ExtensionHostKind, ExtensionRunningPreference } from 'vscode/vscode/vs/workbench/services/extensions/common/extensionHostKind'; import { IExtensionManifestPropertiesService } from 'vscode/vscode/vs/workbench/services/extensions/common/extensionManifestPropertiesService.service'; import { RemoteRunningLocation, LocalProcessRunningLocation, LocalWebWorkerRunningLocation } from 'vscode/vscode/vs/workbench/services/extensions/common/extensionRunningLocation'; let ExtensionRunningLocationTracker = class ExtensionRunningLocationTracker { get maxLocalProcessAffinity() { return this._maxLocalProcessAffinity; } get maxLocalWebWorkerAffinity() { return this._maxLocalWebWorkerAffinity; } constructor(_registry, _extensionHostKindPicker, _environmentService, _configurationService, _logService, _extensionManifestPropertiesService) { this._registry = _registry; this._extensionHostKindPicker = _extensionHostKindPicker; this._environmentService = _environmentService; this._configurationService = _configurationService; this._logService = _logService; this._extensionManifestPropertiesService = _extensionManifestPropertiesService; this._runningLocation = ( new ExtensionIdentifierMap()); this._maxLocalProcessAffinity = 0; this._maxLocalWebWorkerAffinity = 0; } set(extensionId, runningLocation) { this._runningLocation.set(extensionId, runningLocation); } readExtensionKinds(extensionDescription) { if (extensionDescription.isUnderDevelopment && this._environmentService.extensionDevelopmentKind) { return this._environmentService.extensionDevelopmentKind; } return this._extensionManifestPropertiesService.getExtensionKind(extensionDescription); } getRunningLocation(extensionId) { return this._runningLocation.get(extensionId) || null; } filterByRunningLocation(extensions, desiredRunningLocation) { return filterExtensionDescriptions(extensions, this._runningLocation, extRunningLocation => desiredRunningLocation.equals(extRunningLocation)); } filterByExtensionHostKind(extensions, desiredExtensionHostKind) { return filterExtensionDescriptions(extensions, this._runningLocation, extRunningLocation => extRunningLocation.kind === desiredExtensionHostKind); } filterByExtensionHostManager(extensions, extensionHostManager) { return filterExtensionDescriptions(extensions, this._runningLocation, extRunningLocation => extensionHostManager.representsRunningLocation(extRunningLocation)); } _computeAffinity(inputExtensions, extensionHostKind, isInitialAllocation) { const extensions = ( new ExtensionIdentifierMap()); for (const extension of inputExtensions) { if (extension.main || extension.browser) { extensions.set(extension.identifier, extension); } } for (const extension of this._registry.getAllExtensionDescriptions()) { if (extension.main || extension.browser) { const runningLocation = this._runningLocation.get(extension.identifier); if (runningLocation && runningLocation.kind === extensionHostKind) { extensions.set(extension.identifier, extension); } } } const groups = ( new ExtensionIdentifierMap()); let groupNumber = 0; for (const [_, extension] of extensions) { groups.set(extension.identifier, ++groupNumber); } const changeGroup = (from, to) => { for (const [key, group] of groups) { if (group === from) { groups.set(key, to); } } }; for (const [_, extension] of extensions) { if (!extension.extensionDependencies) { continue; } const myGroup = groups.get(extension.identifier); for (const depId of extension.extensionDependencies) { const depGroup = groups.get(depId); if (!depGroup) { continue; } if (depGroup === myGroup) { continue; } changeGroup(depGroup, myGroup); } } const resultingAffinities = ( new Map()); let lastAffinity = 0; for (const [_, extension] of extensions) { const runningLocation = this._runningLocation.get(extension.identifier); if (runningLocation) { const group = groups.get(extension.identifier); resultingAffinities.set(group, runningLocation.affinity); lastAffinity = Math.max(lastAffinity, runningLocation.affinity); } } if (!this._environmentService.isExtensionDevelopment) { const configuredAffinities = this._configurationService.getValue('extensions.experimental.affinity') || {}; const configuredExtensionIds = ( Object.keys(configuredAffinities)); const configuredAffinityToResultingAffinity = ( new Map()); for (const extensionId of configuredExtensionIds) { const configuredAffinity = configuredAffinities[extensionId]; if (typeof configuredAffinity !== 'number' || configuredAffinity <= 0 || Math.floor(configuredAffinity) !== configuredAffinity) { this._logService.info(`Ignoring configured affinity for '${extensionId}' because the value is not a positive integer.`); continue; } const group = groups.get(extensionId); if (!group) { continue; } const affinity1 = resultingAffinities.get(group); if (affinity1) { configuredAffinityToResultingAffinity.set(configuredAffinity, affinity1); continue; } const affinity2 = configuredAffinityToResultingAffinity.get(configuredAffinity); if (affinity2) { resultingAffinities.set(group, affinity2); continue; } if (!isInitialAllocation) { this._logService.info(`Ignoring configured affinity for '${extensionId}' because extension host(s) are already running. Reload window.`); continue; } const affinity3 = ++lastAffinity; configuredAffinityToResultingAffinity.set(configuredAffinity, affinity3); resultingAffinities.set(group, affinity3); } } const result = ( new ExtensionIdentifierMap()); for (const extension of inputExtensions) { const group = groups.get(extension.identifier) || 0; const affinity = resultingAffinities.get(group) || 0; result.set(extension.identifier, affinity); } if (lastAffinity > 0 && isInitialAllocation) { for (let affinity = 1; affinity <= lastAffinity; affinity++) { const extensionIds = []; for (const extension of inputExtensions) { if (result.get(extension.identifier) === affinity) { extensionIds.push(extension.identifier); } } this._logService.info(`Placing extension(s) ${( extensionIds.map(e => e.value)).join(', ')} on a separate extension host.`); } } return { affinities: result, maxAffinity: lastAffinity }; } computeRunningLocation(localExtensions, remoteExtensions, isInitialAllocation) { return this._doComputeRunningLocation(this._runningLocation, localExtensions, remoteExtensions, isInitialAllocation).runningLocation; } _doComputeRunningLocation(existingRunningLocation, localExtensions, remoteExtensions, isInitialAllocation) { localExtensions = localExtensions.filter(extension => !( existingRunningLocation.has(extension.identifier))); remoteExtensions = remoteExtensions.filter(extension => !( existingRunningLocation.has(extension.identifier))); const extensionHostKinds = determineExtensionHostKinds(localExtensions, remoteExtensions, (extension) => this.readExtensionKinds(extension), (extensionId, extensionKinds, isInstalledLocally, isInstalledRemotely, preference) => this._extensionHostKindPicker.pickExtensionHostKind(extensionId, extensionKinds, isInstalledLocally, isInstalledRemotely, preference)); const extensions = ( new ExtensionIdentifierMap()); for (const extension of localExtensions) { extensions.set(extension.identifier, extension); } for (const extension of remoteExtensions) { extensions.set(extension.identifier, extension); } const result = ( new ExtensionIdentifierMap()); const localProcessExtensions = []; const localWebWorkerExtensions = []; for (const [extensionIdKey, extensionHostKind] of extensionHostKinds) { let runningLocation = null; if (extensionHostKind === ExtensionHostKind.LocalProcess) { const extensionDescription = extensions.get(extensionIdKey); if (extensionDescription) { localProcessExtensions.push(extensionDescription); } } else if (extensionHostKind === ExtensionHostKind.LocalWebWorker) { const extensionDescription = extensions.get(extensionIdKey); if (extensionDescription) { localWebWorkerExtensions.push(extensionDescription); } } else if (extensionHostKind === ExtensionHostKind.Remote) { runningLocation = ( new RemoteRunningLocation()); } result.set(extensionIdKey, runningLocation); } const { affinities, maxAffinity } = this._computeAffinity(localProcessExtensions, ExtensionHostKind.LocalProcess, isInitialAllocation); for (const extension of localProcessExtensions) { const affinity = affinities.get(extension.identifier) || 0; result.set(extension.identifier, ( new LocalProcessRunningLocation(affinity))); } const { affinities: localWebWorkerAffinities, maxAffinity: maxLocalWebWorkerAffinity } = this._computeAffinity(localWebWorkerExtensions, ExtensionHostKind.LocalWebWorker, isInitialAllocation); for (const extension of localWebWorkerExtensions) { const affinity = localWebWorkerAffinities.get(extension.identifier) || 0; result.set(extension.identifier, ( new LocalWebWorkerRunningLocation(affinity))); } for (const [extensionIdKey, runningLocation] of existingRunningLocation) { if (runningLocation) { result.set(extensionIdKey, runningLocation); } } return { runningLocation: result, maxLocalProcessAffinity: maxAffinity, maxLocalWebWorkerAffinity: maxLocalWebWorkerAffinity }; } initializeRunningLocation(localExtensions, remoteExtensions) { const { runningLocation, maxLocalProcessAffinity, maxLocalWebWorkerAffinity } = this._doComputeRunningLocation(this._runningLocation, localExtensions, remoteExtensions, true); this._runningLocation = runningLocation; this._maxLocalProcessAffinity = maxLocalProcessAffinity; this._maxLocalWebWorkerAffinity = maxLocalWebWorkerAffinity; } deltaExtensions(toAdd, toRemove) { const removedRunningLocation = ( new ExtensionIdentifierMap()); for (const extensionId of toRemove) { const extensionKey = extensionId; removedRunningLocation.set(extensionKey, this._runningLocation.get(extensionKey) || null); this._runningLocation.delete(extensionKey); } this._updateRunningLocationForAddedExtensions(toAdd); return removedRunningLocation; } _updateRunningLocationForAddedExtensions(toAdd) { const localProcessExtensions = []; const localWebWorkerExtensions = []; for (const extension of toAdd) { const extensionKind = this.readExtensionKinds(extension); const isRemote = extension.extensionLocation.scheme === Schemas.vscodeRemote; const extensionHostKind = this._extensionHostKindPicker.pickExtensionHostKind(extension.identifier, extensionKind, !isRemote, isRemote, ExtensionRunningPreference.None); let runningLocation = null; if (extensionHostKind === ExtensionHostKind.LocalProcess) { localProcessExtensions.push(extension); } else if (extensionHostKind === ExtensionHostKind.LocalWebWorker) { localWebWorkerExtensions.push(extension); } else if (extensionHostKind === ExtensionHostKind.Remote) { runningLocation = ( new RemoteRunningLocation()); } this._runningLocation.set(extension.identifier, runningLocation); } const { affinities } = this._computeAffinity(localProcessExtensions, ExtensionHostKind.LocalProcess, false); for (const extension of localProcessExtensions) { const affinity = affinities.get(extension.identifier) || 0; this._runningLocation.set(extension.identifier, ( new LocalProcessRunningLocation(affinity))); } const { affinities: webWorkerExtensionsAffinities } = this._computeAffinity(localWebWorkerExtensions, ExtensionHostKind.LocalWebWorker, false); for (const extension of localWebWorkerExtensions) { const affinity = webWorkerExtensionsAffinities.get(extension.identifier) || 0; this._runningLocation.set(extension.identifier, ( new LocalWebWorkerRunningLocation(affinity))); } } }; ExtensionRunningLocationTracker = ( __decorate([ ( __param(2, IWorkbenchEnvironmentService)), ( __param(3, IConfigurationService)), ( __param(4, ILogService)), ( __param(5, IExtensionManifestPropertiesService)) ], ExtensionRunningLocationTracker)); function filterExtensionDescriptions(extensions, runningLocation, predicate) { return extensions.filter((ext) => { const extRunningLocation = runningLocation.get(ext.identifier); return extRunningLocation && predicate(extRunningLocation); }); } function filterExtensionIdentifiers(extensions, runningLocation, predicate) { return extensions.filter((ext) => { const extRunningLocation = runningLocation.get(ext); return extRunningLocation && predicate(extRunningLocation); }); } export { ExtensionRunningLocationTracker, filterExtensionDescriptions, filterExtensionIdentifiers };