Skip to content

Commit f59e0c1

Browse files
authored
Merge pull request microsoft#105437 from microsoft/rmacfarlane/earlyAuth
2 parents 32f29cf + df5d0e5 commit f59e0c1

7 files changed

Lines changed: 51 additions & 19 deletions

File tree

extensions/github-authentication/package.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,11 @@
1111
"categories": [
1212
"Other"
1313
],
14+
"extensionKind": [
15+
"ui",
16+
"workspace",
17+
"web"
18+
],
1419
"activationEvents": [
1520
"*",
1621
"onAuthenticationRequest:github"

src/vs/workbench/api/browser/mainThreadAuthentication.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import { INotificationService } from 'vs/platform/notification/common/notificati
1717
import { IStorageKeysSyncRegistryService } from 'vs/platform/userDataSync/common/storageKeys';
1818
import { IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteAgentService';
1919
import { fromNow } from 'vs/base/common/date';
20-
import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions';
20+
import { ActivationKind, IExtensionService } from 'vs/workbench/services/extensions/common/extensions';
2121
import { Platform, platform } from 'vs/base/common/platform';
2222

2323
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
249249
}
250250

251251
$ensureProvider(id: string): Promise<void> {
252-
return this.extensionService.activateByEvent(getAuthenticationProviderActivationEvent(id));
252+
return this.extensionService.activateByEvent(getAuthenticationProviderActivationEvent(id), ActivationKind.Immediate);
253253
}
254254

255255
$sendDidChangeSessions(id: string, event: modes.AuthenticationSessionsChangeEvent): void {

src/vs/workbench/api/common/extHost.protocol.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ import { IRevealOptions, ITreeItem } from 'vs/workbench/common/views';
4242
import { IAdapterDescriptor, IConfig, IDebugSessionReplMode } from 'vs/workbench/contrib/debug/common/debug';
4343
import { ITextQueryBuilderOptions } from 'vs/workbench/contrib/search/common/queryBuilder';
4444
import { ITerminalDimensions, IShellLaunchConfig, ITerminalLaunchError } from 'vs/workbench/contrib/terminal/common/terminal';
45-
import { ExtensionActivationError } from 'vs/workbench/services/extensions/common/extensions';
45+
import { ActivationKind, ExtensionActivationError } from 'vs/workbench/services/extensions/common/extensions';
4646
import { createExtHostContextProxyIdentifier as createExtId, createMainContextProxyIdentifier as createMainId, IRPCProtocol } from 'vs/workbench/services/extensions/common/proxyIdentifier';
4747
import * as search from 'vs/workbench/services/search/common/search';
4848
import { SaveReason } from 'vs/workbench/common/editor';
@@ -1074,7 +1074,7 @@ export type IResolveAuthorityResult = IResolveAuthorityErrorResult | IResolveAut
10741074
export interface ExtHostExtensionServiceShape {
10751075
$resolveAuthority(remoteAuthority: string, resolveAttempt: number): Promise<IResolveAuthorityResult>;
10761076
$startExtensionHost(enabledExtensionIds: ExtensionIdentifier[]): Promise<void>;
1077-
$activateByEvent(activationEvent: string): Promise<void>;
1077+
$activateByEvent(activationEvent: string, activationKind: ActivationKind): Promise<void>;
10781078
$activate(extensionId: ExtensionIdentifier, reason: ExtensionActivationReason): Promise<boolean>;
10791079
$setRemoteEnvironment(env: { [key: string]: string | null; }): Promise<void>;
10801080
$updateRemoteConnectionData(connectionData: IRemoteConnectionData): Promise<void>;

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

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import { ExtHostConfiguration, IExtHostConfiguration } from 'vs/workbench/api/co
1717
import { ActivatedExtension, EmptyExtension, ExtensionActivationReason, ExtensionActivationTimes, ExtensionActivationTimesBuilder, ExtensionsActivator, IExtensionAPI, IExtensionModule, HostExtension, ExtensionActivationTimesFragment } from 'vs/workbench/api/common/extHostExtensionActivator';
1818
import { ExtHostStorage, IExtHostStorage } from 'vs/workbench/api/common/extHostStorage';
1919
import { ExtHostWorkspace, IExtHostWorkspace } from 'vs/workbench/api/common/extHostWorkspace';
20-
import { ExtensionActivationError, checkProposedApiEnabled } from 'vs/workbench/services/extensions/common/extensions';
20+
import { ExtensionActivationError, checkProposedApiEnabled, ActivationKind } from 'vs/workbench/services/extensions/common/extensions';
2121
import { ExtensionDescriptionRegistry } from 'vs/workbench/services/extensions/common/extensionDescriptionRegistry';
2222
import * as errors from 'vs/base/common/errors';
2323
import type * as vscode from 'vscode';
@@ -686,7 +686,11 @@ export abstract class AbstractExtHostExtensionService extends Disposable impleme
686686
return this._startExtensionHost();
687687
}
688688

689-
public $activateByEvent(activationEvent: string): Promise<void> {
689+
public $activateByEvent(activationEvent: string, activationKind: ActivationKind): Promise<void> {
690+
if (activationKind === ActivationKind.Immediate) {
691+
return this._activateByEvent(activationEvent, false);
692+
}
693+
690694
return (
691695
this._readyToRunExtensions.wait()
692696
.then(_ => this._activateByEvent(activationEvent, false))

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

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import { BetterMergeId } from 'vs/platform/extensionManagement/common/extensionM
1515
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
1616
import { INotificationService, Severity } from 'vs/platform/notification/common/notification';
1717
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
18-
import { ActivationTimes, ExtensionPointContribution, IExtensionService, IExtensionsStatus, IMessage, IWillActivateEvent, IResponsiveStateChangeEvent, toExtension, IExtensionHost } from 'vs/workbench/services/extensions/common/extensions';
18+
import { ActivationTimes, ExtensionPointContribution, IExtensionService, IExtensionsStatus, IMessage, IWillActivateEvent, IResponsiveStateChangeEvent, toExtension, IExtensionHost, ActivationKind } from 'vs/workbench/services/extensions/common/extensions';
1919
import { ExtensionMessageCollector, ExtensionPoint, ExtensionsRegistry, IExtensionPoint, IExtensionPointUser } from 'vs/workbench/services/extensions/common/extensionsRegistry';
2020
import { ExtensionDescriptionRegistry } from 'vs/workbench/services/extensions/common/extensionDescriptionRegistry';
2121
import { ResponsiveState } from 'vs/workbench/services/extensions/common/rpcProtocol';
@@ -186,7 +186,7 @@ export abstract class AbstractExtensionService extends Disposable implements IEx
186186
this._startExtensionHosts(false, Array.from(this._allRequestedActivateEvents.keys()));
187187
}
188188

189-
public activateByEvent(activationEvent: string): Promise<void> {
189+
public activateByEvent(activationEvent: string, activationKind: ActivationKind = ActivationKind.Normal): Promise<void> {
190190
if (this._installedExtensionsReady.isOpen()) {
191191
// Extensions have been scanned and interpreted
192192

@@ -198,20 +198,25 @@ export abstract class AbstractExtensionService extends Disposable implements IEx
198198
return NO_OP_VOID_PROMISE;
199199
}
200200

201-
return this._activateByEvent(activationEvent);
201+
return this._activateByEvent(activationEvent, activationKind);
202202
} else {
203203
// Extensions have not been scanned yet.
204204

205205
// Record the fact that this activationEvent was requested (in case of a restart)
206206
this._allRequestedActivateEvents.add(activationEvent);
207207

208-
return this._installedExtensionsReady.wait().then(() => this._activateByEvent(activationEvent));
208+
if (activationKind === ActivationKind.Immediate) {
209+
// Do not wait for the normal start-up of the extension host(s)
210+
return this._activateByEvent(activationEvent, activationKind);
211+
}
212+
213+
return this._installedExtensionsReady.wait().then(() => this._activateByEvent(activationEvent, activationKind));
209214
}
210215
}
211216

212-
private _activateByEvent(activationEvent: string): Promise<void> {
217+
private _activateByEvent(activationEvent: string, activationKind: ActivationKind): Promise<void> {
213218
const result = Promise.all(
214-
this._extensionHostManagers.map(extHostManager => extHostManager.activateByEvent(activationEvent))
219+
this._extensionHostManagers.map(extHostManager => extHostManager.activateByEvent(activationEvent, activationKind))
215220
).then(() => { });
216221
this._onWillActivateByEvent.fire({
217222
event: activationEvent,

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

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ import { registerAction2, Action2 } from 'vs/platform/actions/common/actions';
2121
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
2222
import { StopWatch } from 'vs/base/common/stopwatch';
2323
import { VSBuffer } from 'vs/base/common/buffer';
24-
import { IExtensionHost, ExtensionHostKind } from 'vs/workbench/services/extensions/common/extensions';
24+
import { IExtensionHost, ExtensionHostKind, ActivationKind } from 'vs/workbench/services/extensions/common/extensions';
2525
import { ExtensionActivationReason } from 'vs/workbench/api/common/extHostExtensionActivator';
2626

2727
// Enable to see detailed message communication between window and extension host
@@ -48,6 +48,7 @@ export class ExtensionHostManager extends Disposable {
4848
*/
4949
private _proxy: Promise<{ value: ExtHostExtensionServiceShape; } | null> | null;
5050
private _resolveAuthorityAttempt: number;
51+
private _hasStarted = false;
5152

5253
constructor(
5354
extensionHost: IExtensionHost,
@@ -65,6 +66,7 @@ export class ExtensionHostManager extends Disposable {
6566
this.onDidExit = this._extensionHost.onExit;
6667
this._proxy = this._extensionHost.start()!.then(
6768
(protocol) => {
69+
this._hasStarted = true;
6870
return { value: this._createExtensionHostCustomers(protocol) };
6971
},
7072
(err) => {
@@ -74,7 +76,7 @@ export class ExtensionHostManager extends Disposable {
7476
}
7577
);
7678
this._proxy.then(() => {
77-
initialActivationEvents.forEach((activationEvent) => this.activateByEvent(activationEvent));
79+
initialActivationEvents.forEach((activationEvent) => this.activateByEvent(activationEvent, ActivationKind.Normal));
7880
this._register(registerLatencyTestProvider({
7981
measure: () => this.measure()
8082
}));
@@ -217,14 +219,18 @@ export class ExtensionHostManager extends Disposable {
217219
return proxy.$activate(extension, reason);
218220
}
219221

220-
public activateByEvent(activationEvent: string): Promise<void> {
222+
public activateByEvent(activationEvent: string, activationKind: ActivationKind): Promise<void> {
223+
if (activationKind === ActivationKind.Immediate && !this._hasStarted) {
224+
return Promise.resolve();
225+
}
226+
221227
if (!this._cachedActivationEvents.has(activationEvent)) {
222-
this._cachedActivationEvents.set(activationEvent, this._activateByEvent(activationEvent));
228+
this._cachedActivationEvents.set(activationEvent, this._activateByEvent(activationEvent, activationKind));
223229
}
224230
return this._cachedActivationEvents.get(activationEvent)!;
225231
}
226232

227-
private async _activateByEvent(activationEvent: string): Promise<void> {
233+
private async _activateByEvent(activationEvent: string, activationKind: ActivationKind): Promise<void> {
228234
if (!this._proxy) {
229235
return;
230236
}
@@ -234,7 +240,7 @@ export class ExtensionHostManager extends Disposable {
234240
// i.e. the extension host could not be started
235241
return;
236242
}
237-
return proxy.value.$activateByEvent(activationEvent);
243+
return proxy.value.$activateByEvent(activationEvent, activationKind);
238244
}
239245

240246
public async getInspectPort(tryEnableInspector: boolean): Promise<number> {

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

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,11 @@ export interface IResponsiveStateChangeEvent {
140140
isResponsive: boolean;
141141
}
142142

143+
export const enum ActivationKind {
144+
Normal = 0,
145+
Immediate = 1
146+
}
147+
143148
export interface IExtensionService {
144149
readonly _serviceBrand: undefined;
145150

@@ -177,8 +182,15 @@ export interface IExtensionService {
177182

178183
/**
179184
* Send an activation event and activate interested extensions.
185+
*
186+
* This will wait for the normal startup of the extension host(s).
187+
*
188+
* In extraordinary circumstances, if the activation event needs to activate
189+
* one or more extensions before the normal startup is finished, then you can use
190+
* `ActivationKind.Immediate`. Please do not use this flag unless really necessary
191+
* and you understand all consequences.
180192
*/
181-
activateByEvent(activationEvent: string): Promise<void>;
193+
activateByEvent(activationEvent: string, activationKind?: ActivationKind): Promise<void>;
182194

183195
/**
184196
* An promise that resolves when the installed extensions are registered after

0 commit comments

Comments
 (0)