Skip to content

Commit bccfade

Browse files
authored
Improve handling of extension descriptions (#193145)
1 parent 9c12e02 commit bccfade

File tree

12 files changed

+155
-126
lines changed

12 files changed

+155
-126
lines changed

src/vs/workbench/api/common/extHostExtensionService.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -157,9 +157,9 @@ export abstract class AbstractExtHostExtensionService extends Disposable impleme
157157
this._readyToStartExtensionHost = new Barrier();
158158
this._readyToRunExtensions = new Barrier();
159159
this._eagerExtensionsActivated = new Barrier();
160-
this._activationEventsReader = new SyncedActivationEventsReader(this._initData.activationEvents);
161-
this._globalRegistry = new ExtensionDescriptionRegistry(this._activationEventsReader, this._initData.allExtensions);
162-
const myExtensionsSet = new ExtensionIdentifierSet(this._initData.myExtensions);
160+
this._activationEventsReader = new SyncedActivationEventsReader(this._initData.extensions.activationEvents);
161+
this._globalRegistry = new ExtensionDescriptionRegistry(this._activationEventsReader, this._initData.extensions.allExtensions);
162+
const myExtensionsSet = new ExtensionIdentifierSet(this._initData.extensions.myExtensions);
163163
this._myRegistry = new ExtensionDescriptionRegistry(
164164
this._activationEventsReader,
165165
filterExtensions(this._globalRegistry, myExtensionsSet)

src/vs/workbench/api/common/extensionHostMain.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,7 @@ export class ExtensionHostMain {
194194
}
195195

196196
private static _transform(initData: IExtensionHostInitData, rpcProtocol: RPCProtocol): IExtensionHostInitData {
197-
initData.allExtensions.forEach((ext) => {
197+
initData.extensions.allExtensions.forEach((ext) => {
198198
(<Mutable<IRelaxedExtensionDescription>>ext).extensionLocation = URI.revive(rpcProtocol.transformIncomingURIs(ext.extensionLocation));
199199
});
200200
initData.environment.appRoot = URI.revive(rpcProtocol.transformIncomingURIs(initData.environment.appRoot));

src/vs/workbench/services/extensions/browser/extensionService.ts

Lines changed: 17 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -26,14 +26,15 @@ import { IWebExtensionsScannerService, IWorkbenchExtensionEnablementService, IWo
2626
import { IWebWorkerExtensionHostDataProvider, IWebWorkerExtensionHostInitData, WebWorkerExtensionHost } from 'vs/workbench/services/extensions/browser/webWorkerExtensionHost';
2727
import { FetchFileSystemProvider } from 'vs/workbench/services/extensions/browser/webWorkerFileSystemProvider';
2828
import { AbstractExtensionService, IExtensionHostFactory, ResolvedExtensions, checkEnabledAndProposedAPI } from 'vs/workbench/services/extensions/common/abstractExtensionService';
29+
import { ExtensionDescriptionRegistrySnapshot } from 'vs/workbench/services/extensions/common/extensionDescriptionRegistry';
2930
import { ExtensionHostKind, ExtensionRunningPreference, IExtensionHostKindPicker, extensionHostKindToString, extensionRunningPreferenceToString } from 'vs/workbench/services/extensions/common/extensionHostKind';
3031
import { IExtensionManifestPropertiesService } from 'vs/workbench/services/extensions/common/extensionManifestPropertiesService';
3132
import { ExtensionRunningLocation } from 'vs/workbench/services/extensions/common/extensionRunningLocation';
3233
import { ExtensionRunningLocationTracker, filterExtensionDescriptions } from 'vs/workbench/services/extensions/common/extensionRunningLocationTracker';
33-
import { ExtensionHostStartup, IExtensionHost, IExtensionService, toExtensionDescription } from 'vs/workbench/services/extensions/common/extensions';
34+
import { ExtensionHostExtensions, ExtensionHostStartup, IExtensionHost, IExtensionService, toExtensionDescription } from 'vs/workbench/services/extensions/common/extensions';
3435
import { ExtensionsProposedApi } from 'vs/workbench/services/extensions/common/extensionsProposedApi';
3536
import { dedupExtensions } from 'vs/workbench/services/extensions/common/extensionsUtil';
36-
import { IRemoteExtensionHostDataProvider, RemoteExtensionHost } from 'vs/workbench/services/extensions/common/remoteExtensionHost';
37+
import { IRemoteExtensionHostDataProvider, IRemoteExtensionHostInitData, RemoteExtensionHost } from 'vs/workbench/services/extensions/common/remoteExtensionHost';
3738
import { ILifecycleService, LifecyclePhase } from 'vs/workbench/services/lifecycle/common/lifecycle';
3839
import { IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteAgentService';
3940
import { IRemoteExplorerService } from 'vs/workbench/services/remote/common/remoteExplorerService';
@@ -70,7 +71,7 @@ export class ExtensionService extends AbstractExtensionService implements IExten
7071
const extensionHostFactory = new BrowserExtensionHostFactory(
7172
extensionsProposedApi,
7273
() => this._scanWebExtensions(),
73-
() => this._getExtensions(),
74+
() => this._getExtensionRegistrySnapshotWhenReady(),
7475
instantiationService,
7576
remoteAgentService,
7677
remoteAuthorityResolverService,
@@ -216,7 +217,7 @@ class BrowserExtensionHostFactory implements IExtensionHostFactory {
216217
constructor(
217218
private readonly _extensionsProposedApi: ExtensionsProposedApi,
218219
private readonly _scanWebExtensions: () => Promise<IExtensionDescription[]>,
219-
private readonly _getExtensions: () => Promise<IExtensionDescription[]>,
220+
private readonly _getExtensionRegistrySnapshotWhenReady: () => Promise<ExtensionDescriptionRegistrySnapshot>,
220221
@IInstantiationService private readonly _instantiationService: IInstantiationService,
221222
@IRemoteAgentService private readonly _remoteAgentService: IRemoteAgentService,
222223
@IRemoteAuthorityResolverService private readonly _remoteAuthorityResolverService: IRemoteAuthorityResolverService,
@@ -255,18 +256,14 @@ class BrowserExtensionHostFactory implements IExtensionHostFactory {
255256
const localExtensions = checkEnabledAndProposedAPI(this._logService, this._extensionEnablementService, this._extensionsProposedApi, await this._scanWebExtensions(), /* ignore workspace trust */true);
256257
const runningLocation = runningLocations.computeRunningLocation(localExtensions, [], false);
257258
const myExtensions = filterExtensionDescriptions(localExtensions, runningLocation, extRunningLocation => desiredRunningLocation.equals(extRunningLocation));
258-
return {
259-
allExtensions: localExtensions,
260-
myExtensions: myExtensions.map(extension => extension.identifier)
261-
};
259+
const extensions = new ExtensionHostExtensions(0, localExtensions, myExtensions.map(extension => extension.identifier));
260+
return { extensions };
262261
} else {
263262
// restart case
264-
const allExtensions = await this._getExtensions();
265-
const myExtensions = runningLocations.filterByRunningLocation(allExtensions, desiredRunningLocation);
266-
return {
267-
allExtensions: allExtensions,
268-
myExtensions: myExtensions.map(extension => extension.identifier)
269-
};
263+
const snapshot = await this._getExtensionRegistrySnapshotWhenReady();
264+
const myExtensions = runningLocations.filterByRunningLocation(snapshot.extensions, desiredRunningLocation);
265+
const extensions = new ExtensionHostExtensions(snapshot.versionId, snapshot.extensions, myExtensions.map(extension => extension.identifier));
266+
return { extensions };
270267
}
271268
}
272269
};
@@ -275,28 +272,26 @@ class BrowserExtensionHostFactory implements IExtensionHostFactory {
275272
private _createRemoteExtensionHostDataProvider(runningLocations: ExtensionRunningLocationTracker, remoteAuthority: string): IRemoteExtensionHostDataProvider {
276273
return {
277274
remoteAuthority: remoteAuthority,
278-
getInitData: async () => {
279-
const allExtensions = await this._getExtensions();
275+
getInitData: async (): Promise<IRemoteExtensionHostInitData> => {
276+
const snapshot = await this._getExtensionRegistrySnapshotWhenReady();
280277

281278
const remoteEnv = await this._remoteAgentService.getEnvironment();
282279
if (!remoteEnv) {
283280
throw new Error('Cannot provide init data for remote extension host!');
284281
}
285282

286-
const myExtensions = runningLocations.filterByExtensionHostKind(allExtensions, ExtensionHostKind.Remote);
283+
const myExtensions = runningLocations.filterByExtensionHostKind(snapshot.extensions, ExtensionHostKind.Remote);
284+
const extensions = new ExtensionHostExtensions(snapshot.versionId, snapshot.extensions, myExtensions.map(extension => extension.identifier));
287285

288-
const initData = {
286+
return {
289287
connectionData: this._remoteAuthorityResolverService.getConnectionData(remoteAuthority),
290288
pid: remoteEnv.pid,
291289
appRoot: remoteEnv.appRoot,
292290
extensionHostLogsPath: remoteEnv.extensionHostLogsPath,
293291
globalStorageHome: remoteEnv.globalStorageHome,
294292
workspaceStorageHome: remoteEnv.workspaceStorageHome,
295-
allExtensions: allExtensions,
296-
myExtensions: myExtensions.map(extension => extension.identifier),
293+
extensions,
297294
};
298-
299-
return initData;
300295
}
301296
};
302297
}

src/vs/workbench/services/extensions/browser/webWorkerExtensionHost.ts

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
*--------------------------------------------------------------------------------------------*/
55

66
import * as dom from 'vs/base/browser/dom';
7+
import { parentOriginHash } from 'vs/base/browser/iframe';
78
import { Barrier } from 'vs/base/common/async';
89
import { VSBuffer } from 'vs/base/common/buffer';
910
import { canceled, onUnexpectedError } from 'vs/base/common/errors';
@@ -15,7 +16,6 @@ import { joinPath } from 'vs/base/common/resources';
1516
import { URI } from 'vs/base/common/uri';
1617
import { generateUuid } from 'vs/base/common/uuid';
1718
import { IMessagePassingProtocol } from 'vs/base/parts/ipc/common/ipc';
18-
import { ExtensionIdentifier, IExtensionDescription } from 'vs/platform/extensions/common/extensions';
1919
import { ILabelService } from 'vs/platform/label/common/label';
2020
import { ILayoutService } from 'vs/platform/layout/browser/layoutService';
2121
import { ILogService, ILoggerService } from 'vs/platform/log/common/log';
@@ -25,15 +25,13 @@ import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
2525
import { isLoggingOnly } from 'vs/platform/telemetry/common/telemetryUtils';
2626
import { IUserDataProfilesService } from 'vs/platform/userDataProfile/common/userDataProfile';
2727
import { IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/common/workspace';
28-
import { parentOriginHash } from 'vs/base/browser/iframe';
2928
import { IBrowserWorkbenchEnvironmentService } from 'vs/workbench/services/environment/browser/environmentService';
3029
import { ExtensionHostExitCode, IExtensionHostInitData, MessageType, UIKind, createMessageOfType, isMessageOfType } from 'vs/workbench/services/extensions/common/extensionHostProtocol';
3130
import { LocalWebWorkerRunningLocation } from 'vs/workbench/services/extensions/common/extensionRunningLocation';
3231
import { ExtensionHostExtensions, ExtensionHostStartup, IExtensionHost } from 'vs/workbench/services/extensions/common/extensions';
3332

3433
export interface IWebWorkerExtensionHostInitData {
35-
readonly allExtensions: IExtensionDescription[];
36-
readonly myExtensions: ExtensionIdentifier[];
34+
readonly extensions: ExtensionHostExtensions;
3735
}
3836

3937
export interface IWebWorkerExtensionHostDataProvider {
@@ -43,7 +41,7 @@ export interface IWebWorkerExtensionHostDataProvider {
4341
export class WebWorkerExtensionHost extends Disposable implements IExtensionHost {
4442

4543
public readonly remoteAuthority = null;
46-
public readonly extensions = new ExtensionHostExtensions();
44+
public extensions: ExtensionHostExtensions | null = null;
4745

4846
private readonly _onDidExit = this._register(new Emitter<[number, string | null]>());
4947
public readonly onExit: Event<[number, string | null]> = this._onDidExit.event;
@@ -267,8 +265,8 @@ export class WebWorkerExtensionHost extends Disposable implements IExtensionHost
267265

268266
private async _createExtHostInitData(): Promise<IExtensionHostInitData> {
269267
const initData = await this._initDataProvider.getInitData();
268+
this.extensions = initData.extensions;
270269
const workspace = this._contextService.getWorkspace();
271-
const deltaExtensions = this.extensions.set(initData.allExtensions, initData.myExtensions);
272270
const nlsBaseUrl = this._productService.extensionsGallery?.nlsBaseUrl;
273271
let nlsUrlWithDetails: URI | undefined = undefined;
274272
// Only use the nlsBaseUrl if we are using a language other than the default, English.
@@ -304,9 +302,7 @@ export class WebWorkerExtensionHost extends Disposable implements IExtensionHost
304302
includeStack: false,
305303
logNative: this._environmentService.debugRenderer
306304
},
307-
allExtensions: deltaExtensions.toAdd,
308-
activationEvents: deltaExtensions.addActivationEvents,
309-
myExtensions: deltaExtensions.myToAdd,
305+
extensions: this.extensions.toSnapshot(),
310306
nlsBaseUrl: nlsUrlWithDetails,
311307
telemetryInfo: {
312308
sessionId: this._telemetryService.sessionId,

src/vs/workbench/services/extensions/common/abstractExtensionService.ts

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
3131
import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
3232
import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService';
3333
import { IWorkbenchExtensionEnablementService, IWorkbenchExtensionManagementService } from 'vs/workbench/services/extensionManagement/common/extensionManagement';
34-
import { ExtensionDescriptionRegistryLock, IActivationEventsReader, LockableExtensionDescriptionRegistry } from 'vs/workbench/services/extensions/common/extensionDescriptionRegistry';
34+
import { ExtensionDescriptionRegistryLock, ExtensionDescriptionRegistrySnapshot, IActivationEventsReader, LockableExtensionDescriptionRegistry } from 'vs/workbench/services/extensions/common/extensionDescriptionRegistry';
3535
import { parseExtensionDevOptions } from 'vs/workbench/services/extensions/common/extensionDevOptions';
3636
import { ExtensionHostKind, ExtensionRunningPreference, IExtensionHostKindPicker, extensionHostKindToString } from 'vs/workbench/services/extensions/common/extensionHostKind';
3737
import { IExtensionHostManager, createExtensionHostManager } from 'vs/workbench/services/extensions/common/extensionHostManager';
@@ -298,22 +298,22 @@ export abstract class AbstractExtensionService extends Disposable implements IEx
298298
this._doHandleExtensionPoints((<IExtensionDescription[]>[]).concat(toAdd).concat(toRemove));
299299

300300
// Update the extension host
301-
await this._updateExtensionsOnExtHosts(toAdd, toRemove.map(e => e.identifier));
301+
await this._updateExtensionsOnExtHosts(result.versionId, toAdd, toRemove.map(e => e.identifier));
302302

303303
for (let i = 0; i < toAdd.length; i++) {
304304
this._activateAddedExtensionIfNeeded(toAdd[i]);
305305
}
306306
}
307307

308-
private async _updateExtensionsOnExtHosts(toAdd: IExtensionDescription[], toRemove: ExtensionIdentifier[]): Promise<void> {
308+
private async _updateExtensionsOnExtHosts(versionId: number, toAdd: IExtensionDescription[], toRemove: ExtensionIdentifier[]): Promise<void> {
309309
const removedRunningLocation = this._runningLocations.deltaExtensions(toAdd, toRemove);
310310
const promises = this._extensionHostManagers.map(
311-
extHostManager => this._updateExtensionsOnExtHost(extHostManager, toAdd, toRemove, removedRunningLocation)
311+
extHostManager => this._updateExtensionsOnExtHost(extHostManager, versionId, toAdd, toRemove, removedRunningLocation)
312312
);
313313
await Promise.all(promises);
314314
}
315315

316-
private async _updateExtensionsOnExtHost(extensionHostManager: IExtensionHostManager, toAdd: IExtensionDescription[], toRemove: ExtensionIdentifier[], removedRunningLocation: ExtensionIdentifierMap<ExtensionRunningLocation | null>): Promise<void> {
316+
private async _updateExtensionsOnExtHost(extensionHostManager: IExtensionHostManager, versionId: number, toAdd: IExtensionDescription[], toRemove: ExtensionIdentifier[], removedRunningLocation: ExtensionIdentifierMap<ExtensionRunningLocation | null>): Promise<void> {
317317
const myToAdd = this._runningLocations.filterByExtensionHostManager(toAdd, extensionHostManager);
318318
const myToRemove = filterExtensionIdentifiers(toRemove, removedRunningLocation, extRunningLocation => extensionHostManager.representsRunningLocation(extRunningLocation));
319319
const addActivationEvents = ImplicitActivationEvents.createActivationEventsMap(toAdd);
@@ -322,7 +322,7 @@ export abstract class AbstractExtensionService extends Disposable implements IEx
322322
const printIds = (extensions: ExtensionIdentifier[]) => extensions.map(e => e.value).join(',');
323323
this._logService.info(`AbstractExtensionService: Calling deltaExtensions: toRemove: [${printIds(toRemove)}], toAdd: [${printExtIds(toAdd)}], myToRemove: [${printIds(myToRemove)}], myToAdd: [${printExtIds(myToAdd)}],`);
324324
}
325-
await extensionHostManager.deltaExtensions({ toRemove, toAdd, addActivationEvents, myToRemove, myToAdd: myToAdd.map(extension => extension.identifier) });
325+
await extensionHostManager.deltaExtensions({ versionId, toRemove, toAdd, addActivationEvents, myToRemove, myToAdd: myToAdd.map(extension => extension.identifier) });
326326
}
327327

328328
public canAddExtension(extension: IExtensionDescription): boolean {
@@ -440,11 +440,11 @@ export abstract class AbstractExtensionService extends Disposable implements IEx
440440
this._processExtensions(lock, resolvedExtensions);
441441

442442
// Start extension hosts which are not automatically started
443-
const allExtensions = this._registry.getAllExtensionDescriptions();
443+
const snapshot = this._registry.getSnapshot();
444444
for (const extHostManager of this._extensionHostManagers) {
445445
if (extHostManager.startup !== ExtensionHostStartup.EagerAutoStart) {
446-
const extensions = this._runningLocations.filterByExtensionHostManager(allExtensions, extHostManager);
447-
extHostManager.start(allExtensions, extensions.map(extension => extension.identifier));
446+
const extensions = this._runningLocations.filterByExtensionHostManager(snapshot.extensions, extHostManager);
447+
extHostManager.start(snapshot.versionId, snapshot.extensions, extensions.map(extension => extension.identifier));
448448
}
449449
}
450450
} finally {
@@ -934,8 +934,8 @@ export abstract class AbstractExtensionService extends Disposable implements IEx
934934
return this._registry.getAllExtensionDescriptions();
935935
}
936936

937-
protected _getExtensions(): Promise<IExtensionDescription[]> {
938-
return this._installedExtensionsReady.wait().then(() => this.extensions);
937+
protected _getExtensionRegistrySnapshotWhenReady(): Promise<ExtensionDescriptionRegistrySnapshot> {
938+
return this._installedExtensionsReady.wait().then(() => this._registry.getSnapshot());
939939
}
940940

941941
public getExtension(id: string): Promise<IExtensionDescription | undefined> {

0 commit comments

Comments
 (0)