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 { Schemas } from '../../../../base/common/network.js';
7
>
import { IConfigurationService } from '../../../../platform/configuration/common/configuration.js';
8
>
import { ExtensionKind } from '../../../../platform/environment/common/environment.js';
9
>
import { ExtensionIdentifier, ExtensionIdentifierMap, IExtensionDescription } from '../../../../platform/extensions/common/extensions.js';
10
>
import { ILogService } from '../../../../platform/log/common/log.js';
11
>
import { IWorkbenchEnvironmentService } from '../../environment/common/environmentService.js';
12
>
import { IReadOnlyExtensionDescriptionRegistry } from './extensionDescriptionRegistry.js';
13
>
import { ExtensionHostKind, ExtensionRunningPreference, IExtensionHostKindPicker, determineExtensionHostKinds } from './extensionHostKind.js';
14
>
import { IExtensionHostManager } from './extensionHostManagers.js';
15
>
import { IExtensionManifestPropertiesService } from './extensionManifestPropertiesService.js';
16
>
import { ExtensionRunningLocation, LocalProcessRunningLocation, LocalWebWorkerRunningLocation, RemoteRunningLocation } from './extensionRunningLocation.js';
17
>
import { isProposedApiEnabled } from './extensions.js';
18
>
19
>
export class ExtensionRunningLocationTracker {
20
>
21
>
private _runningLocation = new ExtensionIdentifierMap<ExtensionRunningLocation | null>();
22
>
private _maxLocalProcessAffinity: number = 0;
23
>
private _maxLocalWebWorkerAffinity: number = 0;
24
>
25
>
public get maxLocalProcessAffinity(): number {
26
>
return this._maxLocalProcessAffinity;
27
>
}
28
>
29
>
public get maxLocalWebWorkerAffinity(): number {
30
return this._maxLocalWebWorkerAffinity;
31
}
33
>
constructor(
34
>
private readonly _registry: IReadOnlyExtensionDescriptionRegistry,
35
>
private readonly _extensionHostKindPicker: IExtensionHostKindPicker,
36
>
@IWorkbenchEnvironmentService private readonly _environmentService: IWorkbenchEnvironmentService,
37
>
@IConfigurationService private readonly _configurationService: IConfigurationService,
38
>
@ILogService private readonly _logService: ILogService,
39
>
@IExtensionManifestPropertiesService private readonly _extensionManifestPropertiesService: IExtensionManifestPropertiesService,
40
>
) { }
41
>
42
>
public set(extensionId: ExtensionIdentifier, runningLocation: ExtensionRunningLocation) {
43
this._runningLocation.set(extensionId, runningLocation);
44
}
46
>
public readExtensionKinds(extensionDescription: IExtensionDescription): ExtensionKind[] {
47
>
if (extensionDescription.isUnderDevelopment && this._environmentService.extensionDevelopmentKind) {
48
return this._environmentService.extensionDevelopmentKind;
49
}
51
>
return this._extensionManifestPropertiesService.getExtensionKind(extensionDescription);
52
>
}
53
>
54
>
public getRunningLocation(extensionId: ExtensionIdentifier): ExtensionRunningLocation | null {
55
return this._runningLocation.get(extensionId) || null;
56
}
58
>
public filterByRunningLocation(extensions: readonly IExtensionDescription[], desiredRunningLocation: ExtensionRunningLocation): IExtensionDescription[] {
59
return filterExtensionDescriptions(extensions, this._runningLocation, extRunningLocation => desiredRunningLocation.equals(extRunningLocation));
60
}
62
>
public filterByExtensionHostKind(extensions: readonly IExtensionDescription[], desiredExtensionHostKind: ExtensionHostKind): IExtensionDescription[] {
63
return filterExtensionDescriptions(extensions, this._runningLocation, extRunningLocation => extRunningLocation.kind === desiredExtensionHostKind);
64
}
66
>
public filterByExtensionHostManager(extensions: readonly IExtensionDescription[], extensionHostManager: IExtensionHostManager): IExtensionDescription[] {
67
return filterExtensionDescriptions(extensions, this._runningLocation, extRunningLocation => extensionHostManager.representsRunningLocation(extRunningLocation));
68
}
70
>
private _computeAffinity(inputExtensions: IExtensionDescription[], extensionHostKind: ExtensionHostKind, isInitialAllocation: boolean): { affinities: ExtensionIdentifierMap<number>; maxAffinity: number } {
71
>
// Only analyze extensions that can execute
72
>
const extensions = new ExtensionIdentifierMap<IExtensionDescription>();
73
>
for (const extension of inputExtensions) {
74
>
if (extension.main || extension.browser) {
75
>
extensions.set(extension.identifier, extension);
76
>
}
77
>
}
78
>
// Also add existing extensions of the same kind that can execute
79
>
for (const extension of this._registry.getAllExtensionDescriptions()) {
80
>
if (extension.main || extension.browser) {
81
>
const runningLocation = this._runningLocation.get(extension.identifier);
82
>
if (runningLocation && runningLocation.kind === extensionHostKind) {
83
extensions.set(extension.identifier, extension);
84
}
86
>
}
87
>
88
>
// Initially, each extension belongs to its own group
89
>
const groups = new ExtensionIdentifierMap<number>();
90
>
let groupNumber = 0;
91
>
for (const [_, extension] of extensions) {
92
>
groups.set(extension.identifier, ++groupNumber);
93
>
}
94
>
95
>
const changeGroup = (from: number, to: number) => {
96
for (const [key, group] of groups) {
97
if (group === from) {