diff --git a/src/vs/workbench/api/browser/mainThreadAuthentication.ts b/src/vs/workbench/api/browser/mainThreadAuthentication.ts index e4fde65fb1089d0eecedcfbc2c872955aee0ced0..18493b01c47ab53c31b725fffbe2090b1690b2ac 100644 --- a/src/vs/workbench/api/browser/mainThreadAuthentication.ts +++ b/src/vs/workbench/api/browser/mainThreadAuthentication.ts @@ -17,7 +17,7 @@ import { INotificationService } from 'vs/platform/notification/common/notificati import { IStorageKeysSyncRegistryService } from 'vs/platform/userDataSync/common/storageKeys'; import { IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteAgentService'; import { fromNow } from 'vs/base/common/date'; -import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions'; +import { ActivationKind, IExtensionService } from 'vs/workbench/services/extensions/common/extensions'; import { Platform, platform } from 'vs/base/common/platform'; const VSO_ALLOWED_EXTENSIONS = ['github.vscode-pull-request-github', 'github.vscode-pull-request-github-insiders', 'vscode.git', 'ms-vsonline.vsonline', 'vscode.github-browser']; @@ -249,7 +249,7 @@ export class MainThreadAuthentication extends Disposable implements MainThreadAu } $ensureProvider(id: string): Promise { - return this.extensionService.activateByEvent(getAuthenticationProviderActivationEvent(id), true); + return this.extensionService.activateByEvent(getAuthenticationProviderActivationEvent(id), ActivationKind.Eager); } $sendDidChangeSessions(id: string, event: modes.AuthenticationSessionsChangeEvent): void { diff --git a/src/vs/workbench/api/common/extHost.protocol.ts b/src/vs/workbench/api/common/extHost.protocol.ts index 9f0c4e550659bc7f74608448359f0ccdcd5c700c..5c1f6f97af2859dfabc8ca39c4d3baa4086b11bf 100644 --- a/src/vs/workbench/api/common/extHost.protocol.ts +++ b/src/vs/workbench/api/common/extHost.protocol.ts @@ -42,7 +42,7 @@ import { IRevealOptions, ITreeItem } from 'vs/workbench/common/views'; import { IAdapterDescriptor, IConfig, IDebugSessionReplMode } from 'vs/workbench/contrib/debug/common/debug'; import { ITextQueryBuilderOptions } from 'vs/workbench/contrib/search/common/queryBuilder'; import { ITerminalDimensions, IShellLaunchConfig, ITerminalLaunchError } from 'vs/workbench/contrib/terminal/common/terminal'; -import { ExtensionActivationError } from 'vs/workbench/services/extensions/common/extensions'; +import { ActivationKind, ExtensionActivationError } from 'vs/workbench/services/extensions/common/extensions'; import { createExtHostContextProxyIdentifier as createExtId, createMainContextProxyIdentifier as createMainId, IRPCProtocol } from 'vs/workbench/services/extensions/common/proxyIdentifier'; import * as search from 'vs/workbench/services/search/common/search'; import { SaveReason } from 'vs/workbench/common/editor'; @@ -1074,7 +1074,7 @@ export type IResolveAuthorityResult = IResolveAuthorityErrorResult | IResolveAut export interface ExtHostExtensionServiceShape { $resolveAuthority(remoteAuthority: string, resolveAttempt: number): Promise; $startExtensionHost(enabledExtensionIds: ExtensionIdentifier[]): Promise; - $activateByEvent(activationEvent: string, eager?: boolean): Promise; + $activateByEvent(activationEvent: string, activationKind: ActivationKind): Promise; $activate(extensionId: ExtensionIdentifier, reason: ExtensionActivationReason): Promise; $setRemoteEnvironment(env: { [key: string]: string | null; }): Promise; $updateRemoteConnectionData(connectionData: IRemoteConnectionData): Promise; diff --git a/src/vs/workbench/api/common/extHostExtensionService.ts b/src/vs/workbench/api/common/extHostExtensionService.ts index 0653b623ba0e4ac0908152597bdccbb68358c92a..8d5ab4a9ec844abe0ca3809d3e3caf45d639a252 100644 --- a/src/vs/workbench/api/common/extHostExtensionService.ts +++ b/src/vs/workbench/api/common/extHostExtensionService.ts @@ -17,7 +17,7 @@ import { ExtHostConfiguration, IExtHostConfiguration } from 'vs/workbench/api/co import { ActivatedExtension, EmptyExtension, ExtensionActivationReason, ExtensionActivationTimes, ExtensionActivationTimesBuilder, ExtensionsActivator, IExtensionAPI, IExtensionModule, HostExtension, ExtensionActivationTimesFragment } from 'vs/workbench/api/common/extHostExtensionActivator'; import { ExtHostStorage, IExtHostStorage } from 'vs/workbench/api/common/extHostStorage'; import { ExtHostWorkspace, IExtHostWorkspace } from 'vs/workbench/api/common/extHostWorkspace'; -import { ExtensionActivationError, checkProposedApiEnabled } from 'vs/workbench/services/extensions/common/extensions'; +import { ExtensionActivationError, checkProposedApiEnabled, ActivationKind } from 'vs/workbench/services/extensions/common/extensions'; import { ExtensionDescriptionRegistry } from 'vs/workbench/services/extensions/common/extensionDescriptionRegistry'; import * as errors from 'vs/base/common/errors'; import type * as vscode from 'vscode'; @@ -686,8 +686,8 @@ export abstract class AbstractExtHostExtensionService extends Disposable impleme return this._startExtensionHost(); } - public $activateByEvent(activationEvent: string, eager: boolean = true): Promise { - if (eager) { + public $activateByEvent(activationEvent: string, activationKind: ActivationKind): Promise { + if (activationKind === ActivationKind.Eager) { return this._activateByEvent(activationEvent, false); } diff --git a/src/vs/workbench/services/extensions/common/abstractExtensionService.ts b/src/vs/workbench/services/extensions/common/abstractExtensionService.ts index 2bd2b6a3282f26c72dbfcc17b2ba0caf04de677b..5bd8624bc10e3dce3154102c96cd1742902974f0 100644 --- a/src/vs/workbench/services/extensions/common/abstractExtensionService.ts +++ b/src/vs/workbench/services/extensions/common/abstractExtensionService.ts @@ -15,7 +15,7 @@ import { BetterMergeId } from 'vs/platform/extensionManagement/common/extensionM import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { INotificationService, Severity } from 'vs/platform/notification/common/notification'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; -import { ActivationTimes, ExtensionPointContribution, IExtensionService, IExtensionsStatus, IMessage, IWillActivateEvent, IResponsiveStateChangeEvent, toExtension, IExtensionHost } from 'vs/workbench/services/extensions/common/extensions'; +import { ActivationTimes, ExtensionPointContribution, IExtensionService, IExtensionsStatus, IMessage, IWillActivateEvent, IResponsiveStateChangeEvent, toExtension, IExtensionHost, ActivationKind } from 'vs/workbench/services/extensions/common/extensions'; import { ExtensionMessageCollector, ExtensionPoint, ExtensionsRegistry, IExtensionPoint, IExtensionPointUser } from 'vs/workbench/services/extensions/common/extensionsRegistry'; import { ExtensionDescriptionRegistry } from 'vs/workbench/services/extensions/common/extensionDescriptionRegistry'; import { ResponsiveState } from 'vs/workbench/services/extensions/common/rpcProtocol'; @@ -186,7 +186,7 @@ export abstract class AbstractExtensionService extends Disposable implements IEx this._startExtensionHosts(false, Array.from(this._allRequestedActivateEvents.keys())); } - public activateByEvent(activationEvent: string, eager?: boolean): Promise { + public activateByEvent(activationEvent: string, activationKind: ActivationKind = ActivationKind.Normal): Promise { if (this._installedExtensionsReady.isOpen()) { // Extensions have been scanned and interpreted @@ -198,24 +198,25 @@ export abstract class AbstractExtensionService extends Disposable implements IEx return NO_OP_VOID_PROMISE; } - return this._activateByEvent(activationEvent); + return this._activateByEvent(activationEvent, activationKind); } else { // Extensions have not been scanned yet. // Record the fact that this activationEvent was requested (in case of a restart) this._allRequestedActivateEvents.add(activationEvent); - if (eager) { - return this._activateByEvent(activationEvent, eager); + if (activationKind === ActivationKind.Eager) { + // Do not wait for the normal start-up of the extension host(s) + return this._activateByEvent(activationEvent, activationKind); } - return this._installedExtensionsReady.wait().then(() => this._activateByEvent(activationEvent)); + return this._installedExtensionsReady.wait().then(() => this._activateByEvent(activationEvent, activationKind)); } } - private _activateByEvent(activationEvent: string, eager?: boolean): Promise { + private _activateByEvent(activationEvent: string, activationKind: ActivationKind): Promise { const result = Promise.all( - this._extensionHostManagers.map(extHostManager => extHostManager.activateByEvent(activationEvent, eager)) + this._extensionHostManagers.map(extHostManager => extHostManager.activateByEvent(activationEvent, activationKind)) ).then(() => { }); this._onWillActivateByEvent.fire({ event: activationEvent, diff --git a/src/vs/workbench/services/extensions/common/extensionHostManager.ts b/src/vs/workbench/services/extensions/common/extensionHostManager.ts index e3f7f0c117a0cfdc57f417a7ab3715a0693d8b6f..6bad8c1bde3fd84e8c801a54675b50c739e08abf 100644 --- a/src/vs/workbench/services/extensions/common/extensionHostManager.ts +++ b/src/vs/workbench/services/extensions/common/extensionHostManager.ts @@ -21,7 +21,7 @@ import { registerAction2, Action2 } from 'vs/platform/actions/common/actions'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; import { StopWatch } from 'vs/base/common/stopwatch'; import { VSBuffer } from 'vs/base/common/buffer'; -import { IExtensionHost, ExtensionHostKind } from 'vs/workbench/services/extensions/common/extensions'; +import { IExtensionHost, ExtensionHostKind, ActivationKind } from 'vs/workbench/services/extensions/common/extensions'; import { ExtensionActivationReason } from 'vs/workbench/api/common/extHostExtensionActivator'; // Enable to see detailed message communication between window and extension host @@ -76,7 +76,7 @@ export class ExtensionHostManager extends Disposable { } ); this._proxy.then(() => { - initialActivationEvents.forEach((activationEvent) => this.activateByEvent(activationEvent)); + initialActivationEvents.forEach((activationEvent) => this.activateByEvent(activationEvent, ActivationKind.Normal)); this._register(registerLatencyTestProvider({ measure: () => this.measure() })); @@ -219,18 +219,18 @@ export class ExtensionHostManager extends Disposable { return proxy.$activate(extension, reason); } - public activateByEvent(activationEvent: string, eager?: boolean): Promise { - if (eager && !this._hasStarted) { + public activateByEvent(activationEvent: string, activationKind: ActivationKind): Promise { + if (activationKind === ActivationKind.Eager && !this._hasStarted) { return Promise.resolve(); } if (!this._cachedActivationEvents.has(activationEvent)) { - this._cachedActivationEvents.set(activationEvent, this._activateByEvent(activationEvent, eager)); + this._cachedActivationEvents.set(activationEvent, this._activateByEvent(activationEvent, activationKind)); } return this._cachedActivationEvents.get(activationEvent)!; } - private async _activateByEvent(activationEvent: string, eager?: boolean): Promise { + private async _activateByEvent(activationEvent: string, activationKind: ActivationKind): Promise { if (!this._proxy) { return; } @@ -240,7 +240,7 @@ export class ExtensionHostManager extends Disposable { // i.e. the extension host could not be started return; } - return proxy.value.$activateByEvent(activationEvent, eager); + return proxy.value.$activateByEvent(activationEvent, activationKind); } public async getInspectPort(tryEnableInspector: boolean): Promise { diff --git a/src/vs/workbench/services/extensions/common/extensions.ts b/src/vs/workbench/services/extensions/common/extensions.ts index f0980b0405c96a8755acbcab4fd2a7485c692abd..579f941fecddb21d754ad0ddf0ae7879bb43bf20 100644 --- a/src/vs/workbench/services/extensions/common/extensions.ts +++ b/src/vs/workbench/services/extensions/common/extensions.ts @@ -140,6 +140,11 @@ export interface IResponsiveStateChangeEvent { isResponsive: boolean; } +export const enum ActivationKind { + Normal = 0, + Eager = 1 +} + export interface IExtensionService { readonly _serviceBrand: undefined; @@ -178,12 +183,14 @@ export interface IExtensionService { /** * Send an activation event and activate interested extensions. * - * Normally, this will queue the activation event if the extension hosts are not ready - * and send it to all of them. If the extension needs to be activated before this, - * the eager flag can be used to ignore extension hosts that aren't yet started. Do not - * use this flag unless necessary. + * This will wait for the normal startup of the extension host(s). + * + * In extraordinary circumstances, if the activation event needs to activate + * one or more extensions before the normal startup is finished, then you can use + * `ActivationKind.Eager`. Please do not use this flag unless really necessary + * and you understand all consequences. */ - activateByEvent(activationEvent: string, eager?: boolean): Promise; + activateByEvent(activationEvent: string, activationKind?: ActivationKind): Promise; /** * An promise that resolves when the installed extensions are registered after