From 27c07934d7d538f6799dc78dc19a174f8e31aaa7 Mon Sep 17 00:00:00 2001 From: Alex Dima Date: Fri, 25 Aug 2017 11:42:02 +0200 Subject: [PATCH] Have a `startup` flag in the extensions activation times --- .../actions/test/common/menuService.test.ts | 8 +++-- .../commands/test/commandService.test.ts | 3 ++ .../platform/extensions/common/extensions.ts | 4 ++- .../mainThreadExtensionService.ts | 4 +-- src/vs/workbench/api/node/extHost.api.impl.ts | 2 +- src/vs/workbench/api/node/extHost.protocol.ts | 2 +- .../api/node/extHostExtensionActivator.ts | 33 +++++++++++-------- .../api/node/extHostExtensionService.ts | 28 ++++++++-------- src/vs/workbench/node/extensionHostMain.ts | 4 +-- .../electron-browser/extensionService.ts | 4 +-- 10 files changed, 53 insertions(+), 39 deletions(-) diff --git a/src/vs/platform/actions/test/common/menuService.test.ts b/src/vs/platform/actions/test/common/menuService.test.ts index e482d1a0f32..87eb693b611 100644 --- a/src/vs/platform/actions/test/common/menuService.test.ts +++ b/src/vs/platform/actions/test/common/menuService.test.ts @@ -12,7 +12,7 @@ import { NullCommandService } from 'vs/platform/commands/common/commands'; import { MockContextKeyService } from 'vs/platform/keybinding/test/common/mockKeybindingService'; import { IExtensionPoint } from 'vs/platform/extensions/common/extensionsRegistry'; import { TPromise } from 'vs/base/common/winjs.base'; -import { ExtensionPointContribution, IExtensionDescription, IExtensionsStatus, IExtensionService } from 'vs/platform/extensions/common/extensions'; +import { ExtensionPointContribution, IExtensionDescription, IExtensionsStatus, IExtensionService, ActivationTimes } from 'vs/platform/extensions/common/extensions'; // --- service instances @@ -35,7 +35,11 @@ class MockExtensionService implements IExtensionService { throw new Error('Not implemented'); } - public getExtensionsStatus(): { [id: string]: IExtensionsStatus } { + public getExtensionsStatus(): { [id: string]: IExtensionsStatus; } { + throw new Error('Not implemented'); + } + + public getExtensionsActivationTimes(): { [id: string]: ActivationTimes; } { throw new Error('Not implemented'); } diff --git a/src/vs/platform/commands/test/commandService.test.ts b/src/vs/platform/commands/test/commandService.test.ts index 1b47b458c49..c027ea01257 100644 --- a/src/vs/platform/commands/test/commandService.test.ts +++ b/src/vs/platform/commands/test/commandService.test.ts @@ -27,6 +27,9 @@ class SimpleExtensionService implements IExtensionService { getExtensionsStatus() { return undefined; } + getExtensionsActivationTimes() { + return undefined; + } getExtensions(): TPromise { return TPromise.wrap([]); } diff --git a/src/vs/platform/extensions/common/extensions.ts b/src/vs/platform/extensions/common/extensions.ts index f80d3e04bbc..96e2c0832d3 100644 --- a/src/vs/platform/extensions/common/extensions.ts +++ b/src/vs/platform/extensions/common/extensions.ts @@ -41,11 +41,13 @@ export interface IExtensionsStatus { } export class ActivationTimes { + public readonly startup: boolean; public readonly codeLoadingTime: number; public readonly activateCallTime: number; public readonly activateResolvedTime: number; - constructor(codeLoadingTime: number, activateCallTime: number, activateResolvedTime: number) { + constructor(startup: boolean, codeLoadingTime: number, activateCallTime: number, activateResolvedTime: number) { + this.startup = startup; this.codeLoadingTime = codeLoadingTime; this.activateCallTime = activateCallTime; this.activateResolvedTime = activateResolvedTime; diff --git a/src/vs/workbench/api/electron-browser/mainThreadExtensionService.ts b/src/vs/workbench/api/electron-browser/mainThreadExtensionService.ts index f549464c9e8..ea48b3c3a40 100644 --- a/src/vs/workbench/api/electron-browser/mainThreadExtensionService.ts +++ b/src/vs/workbench/api/electron-browser/mainThreadExtensionService.ts @@ -30,8 +30,8 @@ export class MainThreadExtensionService implements MainThreadExtensionServiceSha $localShowMessage(severity: Severity, msg: string): void { this._extensionService._logOrShowMessage(severity, msg); } - $onExtensionActivated(extensionId: string, codeLoadingTime: number, activateCallTime: number, activateResolvedTime: number): void { - this._extensionService._onExtensionActivated(extensionId, codeLoadingTime, activateCallTime, activateResolvedTime); + $onExtensionActivated(extensionId: string, startup: boolean, codeLoadingTime: number, activateCallTime: number, activateResolvedTime: number): void { + this._extensionService._onExtensionActivated(extensionId, startup, codeLoadingTime, activateCallTime, activateResolvedTime); } $onExtensionActivationFailed(extensionId: string): void { } diff --git a/src/vs/workbench/api/node/extHost.api.impl.ts b/src/vs/workbench/api/node/extHost.api.impl.ts index 43b01031087..bfd4b85fb69 100644 --- a/src/vs/workbench/api/node/extHost.api.impl.ts +++ b/src/vs/workbench/api/node/extHost.api.impl.ts @@ -619,7 +619,7 @@ class Extension implements vscode.Extension { } activate(): Thenable { - return this._extensionService.activateById(this.id).then(() => this.exports); + return this._extensionService.activateById(this.id, false).then(() => this.exports); } } diff --git a/src/vs/workbench/api/node/extHost.protocol.ts b/src/vs/workbench/api/node/extHost.protocol.ts index 204c0711973..c8ea08fd706 100644 --- a/src/vs/workbench/api/node/extHost.protocol.ts +++ b/src/vs/workbench/api/node/extHost.protocol.ts @@ -306,7 +306,7 @@ export interface MainThreadTaskShape extends IDisposable { export interface MainThreadExtensionServiceShape extends IDisposable { $localShowMessage(severity: Severity, msg: string): void; - $onExtensionActivated(extensionId: string, codeLoadingTime: number, activateCallTime: number, activateResolvedTime: number): void; + $onExtensionActivated(extensionId: string, startup: boolean, codeLoadingTime: number, activateCallTime: number, activateResolvedTime: number): void; $onExtensionActivationFailed(extensionId: string): void; } diff --git a/src/vs/workbench/api/node/extHostExtensionActivator.ts b/src/vs/workbench/api/node/extHostExtensionActivator.ts index 25006973323..4d674591ad1 100644 --- a/src/vs/workbench/api/node/extHostExtensionActivator.ts +++ b/src/vs/workbench/api/node/extHostExtensionActivator.ts @@ -45,13 +45,15 @@ export interface IExtensionAPI { export class ExtensionActivationTimes { - public static NONE = new ExtensionActivationTimes(-1, -1, -1); + public static NONE = new ExtensionActivationTimes(false, -1, -1, -1); + public readonly startup: boolean; public readonly codeLoadingTime: number; public readonly activateCallTime: number; public readonly activateResolvedTime: number; - constructor(codeLoadingTime: number, activateCallTime: number, activateResolvedTime: number) { + constructor(startup: boolean, codeLoadingTime: number, activateCallTime: number, activateResolvedTime: number) { + this.startup = startup; this.codeLoadingTime = codeLoadingTime; this.activateCallTime = activateCallTime; this.activateResolvedTime = activateResolvedTime; @@ -60,6 +62,7 @@ export class ExtensionActivationTimes { export class ExtensionActivationTimesBuilder { + private readonly _startup: boolean; private _codeLoadingStart: number; private _codeLoadingStop: number; private _activateCallStart: number; @@ -67,7 +70,8 @@ export class ExtensionActivationTimesBuilder { private _activateResolveStart: number; private _activateResolveStop: number; - constructor() { + constructor(startup: boolean) { + this._startup = startup; this._codeLoadingStart = -1; this._codeLoadingStop = -1; this._activateCallStart = -1; @@ -85,6 +89,7 @@ export class ExtensionActivationTimesBuilder { public build(): ExtensionActivationTimes { return new ExtensionActivationTimes( + this._startup, this._delta(this._codeLoadingStart, this._codeLoadingStop), this._delta(this._activateCallStart, this._activateCallStop), this._delta(this._activateResolveStart, this._activateResolveStop) @@ -154,7 +159,7 @@ export class FailedExtension extends ActivatedExtension { export interface IExtensionsActivatorHost { showMessage(severity: Severity, message: string): void; - actualActivateExtension(extensionDescription: IExtensionDescription): TPromise; + actualActivateExtension(extensionDescription: IExtensionDescription, startup: boolean): TPromise; } export class ExtensionsActivator { @@ -187,23 +192,23 @@ export class ExtensionsActivator { return this._activatedExtensions[extensionId]; } - public activateByEvent(activationEvent: string): TPromise { + public activateByEvent(activationEvent: string, startup: boolean): TPromise { if (this._alreadyActivatedEvents[activationEvent]) { return NO_OP_VOID_PROMISE; } let activateExtensions = this._registry.getExtensionDescriptionsForActivationEvent(activationEvent); - return this._activateExtensions(activateExtensions, 0).then(() => { + return this._activateExtensions(activateExtensions, startup, 0).then(() => { this._alreadyActivatedEvents[activationEvent] = true; }); } - public activateById(extensionId: string): TPromise { + public activateById(extensionId: string, startup: boolean): TPromise { let desc = this._registry.getExtensionDescription(extensionId); if (!desc) { throw new Error('Extension `' + extensionId + '` is not known'); } - return this._activateExtensions([desc], 0); + return this._activateExtensions([desc], startup, 0); } /** @@ -247,7 +252,7 @@ export class ExtensionsActivator { } } - private _activateExtensions(extensionDescriptions: IExtensionDescription[], recursionLevel: number): TPromise { + private _activateExtensions(extensionDescriptions: IExtensionDescription[], startup: boolean, recursionLevel: number): TPromise { // console.log(recursionLevel, '_activateExtensions: ', extensionDescriptions.map(p => p.id)); if (extensionDescriptions.length === 0) { return TPromise.as(void 0); @@ -289,15 +294,15 @@ export class ExtensionsActivator { if (red.length === 0) { // Finally reached only leafs! - return TPromise.join(green.map((p) => this._activateExtension(p))).then(_ => void 0); + return TPromise.join(green.map((p) => this._activateExtension(p, startup))).then(_ => void 0); } - return this._activateExtensions(green, recursionLevel + 1).then(_ => { - return this._activateExtensions(red, recursionLevel + 1); + return this._activateExtensions(green, startup, recursionLevel + 1).then(_ => { + return this._activateExtensions(red, startup, recursionLevel + 1); }); } - private _activateExtension(extensionDescription: IExtensionDescription): TPromise { + private _activateExtension(extensionDescription: IExtensionDescription, startup: boolean): TPromise { if (hasOwnProperty.call(this._activatedExtensions, extensionDescription.id)) { return TPromise.as(void 0); } @@ -306,7 +311,7 @@ export class ExtensionsActivator { return this._activatingExtensions[extensionDescription.id]; } - this._activatingExtensions[extensionDescription.id] = this._host.actualActivateExtension(extensionDescription).then(null, (err) => { + this._activatingExtensions[extensionDescription.id] = this._host.actualActivateExtension(extensionDescription, startup).then(null, (err) => { this._host.showMessage(Severity.Error, nls.localize('activationError', "Activating extension `{0}` failed: {1}.", extensionDescription.id, err.message)); console.error('Activating extension `' + extensionDescription.id + '` failed: ', err.message); console.log('Here is the error stack: ', err.stack); diff --git a/src/vs/workbench/api/node/extHostExtensionService.ts b/src/vs/workbench/api/node/extHostExtensionService.ts index 78872e44790..53623e85b43 100644 --- a/src/vs/workbench/api/node/extHostExtensionService.ts +++ b/src/vs/workbench/api/node/extHostExtensionService.ts @@ -151,8 +151,8 @@ export class ExtHostExtensionService implements ExtHostExtensionServiceShape { } }, - actualActivateExtension: (extensionDescription: IExtensionDescription): TPromise => { - return this._activateExtension(extensionDescription); + actualActivateExtension: (extensionDescription: IExtensionDescription, startup: boolean): TPromise => { + return this._activateExtension(extensionDescription, startup); } }); @@ -171,19 +171,19 @@ export class ExtHostExtensionService implements ExtHostExtensionServiceShape { return false; } - public activateByEvent(activationEvent: string): TPromise { + public activateByEvent(activationEvent: string, startup: boolean): TPromise { if (this._barrier.isOpen()) { - return this._activator.activateByEvent(activationEvent); + return this._activator.activateByEvent(activationEvent, startup); } else { - return this._barrier.wait().then(() => this._activator.activateByEvent(activationEvent)); + return this._barrier.wait().then(() => this._activator.activateByEvent(activationEvent, startup)); } } - public activateById(extensionId: string): TPromise { + public activateById(extensionId: string, startup: boolean): TPromise { if (this._barrier.isOpen()) { - return this._activator.activateById(extensionId); + return this._activator.activateById(extensionId, startup); } else { - return this._barrier.wait().then(() => this._activator.activateById(extensionId)); + return this._barrier.wait().then(() => this._activator.activateById(extensionId, startup)); } } @@ -268,10 +268,10 @@ export class ExtHostExtensionService implements ExtHostExtensionServiceShape { // --- impl - private _activateExtension(extensionDescription: IExtensionDescription): TPromise { - return this._doActivateExtension(extensionDescription).then((activatedExtension) => { + private _activateExtension(extensionDescription: IExtensionDescription, startup: boolean): TPromise { + return this._doActivateExtension(extensionDescription, startup).then((activatedExtension) => { const activationTimes = activatedExtension.activationTimes; - this._proxy.$onExtensionActivated(extensionDescription.id, activationTimes.codeLoadingTime, activationTimes.activateCallTime, activationTimes.activateResolvedTime); + this._proxy.$onExtensionActivated(extensionDescription.id, activationTimes.startup, activationTimes.codeLoadingTime, activationTimes.activateCallTime, activationTimes.activateResolvedTime); return activatedExtension; }, (err) => { this._proxy.$onExtensionActivationFailed(extensionDescription.id); @@ -279,7 +279,7 @@ export class ExtHostExtensionService implements ExtHostExtensionServiceShape { }); } - private _doActivateExtension(extensionDescription: IExtensionDescription): TPromise { + private _doActivateExtension(extensionDescription: IExtensionDescription, startup: boolean): TPromise { let event = getTelemetryActivationEvent(extensionDescription); this._mainThreadTelemetry.$publicLog('activatePlugin', event); if (!extensionDescription.main) { @@ -287,7 +287,7 @@ export class ExtHostExtensionService implements ExtHostExtensionServiceShape { return TPromise.as(new EmptyExtension(ExtensionActivationTimes.NONE)); } - const activationTimesBuilder = new ExtensionActivationTimesBuilder(); + const activationTimesBuilder = new ExtensionActivationTimesBuilder(startup); return TPromise.join([ loadCommonJSModule(extensionDescription.main, activationTimesBuilder), this._loadExtensionContext(extensionDescription) @@ -362,7 +362,7 @@ export class ExtHostExtensionService implements ExtHostExtensionServiceShape { // -- called by main thread public $activateByEvent(activationEvent: string): TPromise { - return this.activateByEvent(activationEvent); + return this.activateByEvent(activationEvent, false); } } diff --git a/src/vs/workbench/node/extensionHostMain.ts b/src/vs/workbench/node/extensionHostMain.ts index 01e7f509137..c12d098e75c 100644 --- a/src/vs/workbench/node/extensionHostMain.ts +++ b/src/vs/workbench/node/extensionHostMain.ts @@ -115,7 +115,7 @@ export class ExtensionHostMain { // Handle "eager" activation extensions private handleEagerExtensions(): TPromise { - this._extensionService.activateByEvent('*').then(null, (err) => { + this._extensionService.activateByEvent('*', true).then(null, (err) => { console.error(err); }); return this.handleWorkspaceContainsEagerExtensions(); @@ -181,7 +181,7 @@ export class ExtensionHostMain { .forEach(p => { const activationEvent = `workspaceContains:${p}`; - this._extensionService.activateByEvent(activationEvent) + this._extensionService.activateByEvent(activationEvent, true) .done(null, err => console.error(err)); }); }); diff --git a/src/vs/workbench/services/extensions/electron-browser/extensionService.ts b/src/vs/workbench/services/extensions/electron-browser/extensionService.ts index cbc7a4dffc6..69c5ae81059 100644 --- a/src/vs/workbench/services/extensions/electron-browser/extensionService.ts +++ b/src/vs/workbench/services/extensions/electron-browser/extensionService.ts @@ -419,8 +419,8 @@ export class ExtensionService implements IExtensionService { } } - public _onExtensionActivated(extensionId: string, codeLoadingTime: number, activateCallTime: number, activateResolvedTime: number): void { - this._extensionHostProcessActivationTimes[extensionId] = new ActivationTimes(codeLoadingTime, activateCallTime, activateResolvedTime); + public _onExtensionActivated(extensionId: string, startup: boolean, codeLoadingTime: number, activateCallTime: number, activateResolvedTime: number): void { + this._extensionHostProcessActivationTimes[extensionId] = new ActivationTimes(startup, codeLoadingTime, activateCallTime, activateResolvedTime); } }