Skip to content

Commit 66f719f

Browse files
committed
Share code via AbstractExtensionService
1 parent 273b73d commit 66f719f

File tree

4 files changed

+123
-189
lines changed

4 files changed

+123
-189
lines changed

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

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

66
import { Schemas } from 'vs/base/common/network';
7-
import { StopWatch } from 'vs/base/common/stopwatch';
87
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
98
import { ExtensionKind } from 'vs/platform/environment/common/environment';
109
import { ExtensionIdentifier, ExtensionType, IExtension, IExtensionDescription } from 'vs/platform/extensions/common/extensions';
@@ -16,7 +15,7 @@ import { ILogService } from 'vs/platform/log/common/log';
1615
import { INotificationService } from 'vs/platform/notification/common/notification';
1716
import { IProductService } from 'vs/platform/product/common/productService';
1817
import { PersistentConnectionEventType } from 'vs/platform/remote/common/remoteAgentConnection';
19-
import { IRemoteAuthorityResolverService, RemoteAuthorityResolverError, RemoteAuthorityResolverErrorCode, ResolverResult, getRemoteAuthorityPrefix } from 'vs/platform/remote/common/remoteAuthorityResolver';
18+
import { IRemoteAuthorityResolverService, RemoteAuthorityResolverError, ResolverResult } from 'vs/platform/remote/common/remoteAuthorityResolver';
2019
import { IRemoteExtensionsScannerService } from 'vs/platform/remote/common/remoteExtensionsScanner';
2120
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
2221
import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
@@ -27,7 +26,6 @@ import { IWebWorkerExtensionHostDataProvider, IWebWorkerExtensionHostInitData, W
2726
import { FetchFileSystemProvider } from 'vs/workbench/services/extensions/browser/webWorkerFileSystemProvider';
2827
import { AbstractExtensionService, IExtensionHostFactory, ResolvedExtensions, checkEnabledAndProposedAPI } from 'vs/workbench/services/extensions/common/abstractExtensionService';
2928
import { ExtensionHostKind, ExtensionRunningPreference, IExtensionHostKindPicker, extensionHostKindToString, extensionRunningPreferenceToString } from 'vs/workbench/services/extensions/common/extensionHostKind';
30-
import { IResolveAuthorityErrorResult } from 'vs/workbench/services/extensions/common/extensionHostProxy';
3129
import { IExtensionManifestPropertiesService } from 'vs/workbench/services/extensions/common/extensionManifestPropertiesService';
3230
import { ExtensionRunningLocation } from 'vs/workbench/services/extensions/common/extensionRunningLocation';
3331
import { ExtensionRunningLocationTracker, filterExtensionDescriptions } from 'vs/workbench/services/extensions/common/extensionRunningLocationTracker';
@@ -43,8 +41,6 @@ import { IUserDataProfileService } from 'vs/workbench/services/userDataProfile/c
4341

4442
export class ExtensionService extends AbstractExtensionService implements IExtensionService {
4543

46-
private _resolveAuthorityAttempt: number = 0;
47-
4844
constructor(
4945
@IInstantiationService instantiationService: IInstantiationService,
5046
@INotificationService notificationService: INotificationService,
@@ -62,7 +58,7 @@ export class ExtensionService extends AbstractExtensionService implements IExten
6258
@IRemoteAgentService remoteAgentService: IRemoteAgentService,
6359
@IRemoteExtensionsScannerService remoteExtensionsScannerService: IRemoteExtensionsScannerService,
6460
@ILifecycleService lifecycleService: ILifecycleService,
65-
@IRemoteAuthorityResolverService private readonly _remoteAuthorityResolverService: IRemoteAuthorityResolverService,
61+
@IRemoteAuthorityResolverService remoteAuthorityResolverService: IRemoteAuthorityResolverService,
6662
@IUserDataInitializationService private readonly _userDataInitializationService: IUserDataInitializationService,
6763
@IUserDataProfileService private readonly _userDataProfileService: IUserDataProfileService,
6864
@IWorkspaceTrustManagementService private readonly _workspaceTrustManagementService: IWorkspaceTrustManagementService,
@@ -75,7 +71,7 @@ export class ExtensionService extends AbstractExtensionService implements IExten
7571
() => this._getExtensions(),
7672
instantiationService,
7773
remoteAgentService,
78-
_remoteAuthorityResolverService,
74+
remoteAuthorityResolverService,
7975
extensionEnablementService
8076
);
8177
super(
@@ -96,7 +92,8 @@ export class ExtensionService extends AbstractExtensionService implements IExten
9692
logService,
9793
remoteAgentService,
9894
remoteExtensionsScannerService,
99-
lifecycleService
95+
lifecycleService,
96+
remoteAuthorityResolverService
10097
);
10198

10299
// Initialize installed extensions first and do it only after workbench is ready
@@ -205,93 +202,8 @@ export class ExtensionService extends AbstractExtensionService implements IExten
205202
}
206203
}
207204

208-
// impl
209-
210-
private async _resolveAuthorityAgain(): Promise<void> {
211-
const remoteAuthority = this._environmentService.remoteAuthority;
212-
if (!remoteAuthority) {
213-
return;
214-
}
215-
216-
this._remoteAuthorityResolverService._clearResolvedAuthority(remoteAuthority);
217-
try {
218-
const result = await this._resolveAuthorityWithLogging(remoteAuthority);
219-
this._remoteAuthorityResolverService._setResolvedAuthority(result.authority, result.options);
220-
} catch (err) {
221-
this._remoteAuthorityResolverService._setResolvedAuthorityError(remoteAuthority, err);
222-
}
223-
}
224-
225-
private async _resolveAuthorityInitial(remoteAuthority: string): Promise<ResolverResult> {
226-
const MAX_ATTEMPTS = 5;
227-
228-
for (let attempt = 1; ; attempt++) {
229-
try {
230-
return this._resolveAuthorityWithLogging(remoteAuthority);
231-
} catch (err) {
232-
if (RemoteAuthorityResolverError.isNoResolverFound(err)) {
233-
// There is no point in retrying if there is no resolver found
234-
throw err;
235-
}
236-
237-
if (RemoteAuthorityResolverError.isNotAvailable(err)) {
238-
// The resolver is not available and asked us to not retry
239-
throw err;
240-
}
241-
242-
if (attempt >= MAX_ATTEMPTS) {
243-
// Too many failed attempts, give up
244-
throw err;
245-
}
246-
}
247-
}
248-
}
249-
250-
private async _resolveAuthorityWithLogging(remoteAuthority: string): Promise<ResolverResult> {
251-
const authorityPrefix = getRemoteAuthorityPrefix(remoteAuthority);
252-
const sw = StopWatch.create(false);
253-
this._logService.info(`Invoking resolveAuthority(${authorityPrefix})...`);
254-
try {
255-
performance.mark(`code/willResolveAuthority/${authorityPrefix}`);
256-
const result = await this._resolveAuthority(remoteAuthority);
257-
performance.mark(`code/didResolveAuthorityOK/${authorityPrefix}`);
258-
this._logService.info(`resolveAuthority(${authorityPrefix}) returned '${result.authority.connectTo}' after ${sw.elapsed()} ms`);
259-
return result;
260-
} catch (err) {
261-
performance.mark(`code/didResolveAuthorityError/${authorityPrefix}`);
262-
this._logService.error(`resolveAuthority(${authorityPrefix}) returned an error after ${sw.elapsed()} ms`, err);
263-
throw err;
264-
}
265-
}
266-
267-
private async _resolveAuthority(remoteAuthority: string): Promise<ResolverResult> {
268-
const localWebWorkerExtensionHosts = this._getExtensionHostManagers(ExtensionHostKind.LocalWebWorker);
269-
if (localWebWorkerExtensionHosts.length === 0) {
270-
// no local process extension hosts
271-
throw new Error(`Cannot resolve authority`);
272-
}
273-
274-
this._resolveAuthorityAttempt++;
275-
const results = await Promise.all(localWebWorkerExtensionHosts.map(extHost => extHost.resolveAuthority(remoteAuthority, this._resolveAuthorityAttempt)));
276-
277-
let bestErrorResult: IResolveAuthorityErrorResult | null = null;
278-
for (const result of results) {
279-
if (result.type === 'ok') {
280-
return result.value;
281-
}
282-
if (!bestErrorResult) {
283-
bestErrorResult = result;
284-
continue;
285-
}
286-
const bestErrorIsUnknown = (bestErrorResult.error.code === RemoteAuthorityResolverErrorCode.Unknown);
287-
const errorIsUnknown = (result.error.code === RemoteAuthorityResolverErrorCode.Unknown);
288-
if (bestErrorIsUnknown && !errorIsUnknown) {
289-
bestErrorResult = result;
290-
}
291-
}
292-
293-
// we can only reach this if there is an error
294-
throw new RemoteAuthorityResolverError(bestErrorResult!.error.message, bestErrorResult!.error.code, bestErrorResult!.error.detail);
205+
protected async _resolveAuthority(remoteAuthority: string): Promise<ResolverResult> {
206+
return this._resolveAuthorityOnExtensionHosts(ExtensionHostKind.LocalWebWorker, remoteAuthority);
295207
}
296208
}
297209

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

Lines changed: 100 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import { Disposable } from 'vs/base/common/lifecycle';
99
import { Schemas } from 'vs/base/common/network';
1010
import * as perf from 'vs/base/common/performance';
1111
import { isEqualOrParent } from 'vs/base/common/resources';
12+
import { StopWatch } from 'vs/base/common/stopwatch';
1213
import { URI } from 'vs/base/common/uri';
1314
import * as nls from 'vs/nls';
1415
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
@@ -21,6 +22,7 @@ import { handleVetos } from 'vs/platform/lifecycle/common/lifecycle';
2122
import { ILogService } from 'vs/platform/log/common/log';
2223
import { INotificationService, Severity } from 'vs/platform/notification/common/notification';
2324
import { IProductService } from 'vs/platform/product/common/productService';
25+
import { IRemoteAuthorityResolverService, RemoteAuthorityResolverError, RemoteAuthorityResolverErrorCode, ResolverResult, getRemoteAuthorityPrefix } from 'vs/platform/remote/common/remoteAuthorityResolver';
2426
import { IRemoteExtensionsScannerService } from 'vs/platform/remote/common/remoteExtensionsScanner';
2527
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
2628
import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
@@ -30,6 +32,7 @@ import { ExtensionDescriptionRegistryLock, IActivationEventsReader, LockableExte
3032
import { parseExtensionDevOptions } from 'vs/workbench/services/extensions/common/extensionDevOptions';
3133
import { ExtensionHostKind, ExtensionRunningPreference, IExtensionHostKindPicker, extensionHostKindToString } from 'vs/workbench/services/extensions/common/extensionHostKind';
3234
import { IExtensionHostManager, createExtensionHostManager } from 'vs/workbench/services/extensions/common/extensionHostManager';
35+
import { IResolveAuthorityErrorResult } from 'vs/workbench/services/extensions/common/extensionHostProxy';
3336
import { IExtensionManifestPropertiesService } from 'vs/workbench/services/extensions/common/extensionManifestPropertiesService';
3437
import { ExtensionRunningLocation, LocalProcessRunningLocation, LocalWebWorkerRunningLocation, RemoteRunningLocation } from 'vs/workbench/services/extensions/common/extensionRunningLocation';
3538
import { ExtensionRunningLocationTracker, filterExtensionIdentifiers } from 'vs/workbench/services/extensions/common/extensionRunningLocationTracker';
@@ -79,6 +82,8 @@ export abstract class AbstractExtensionService extends Disposable implements IEx
7982

8083
private _extensionHostManagers: IExtensionHostManager[] = [];
8184

85+
private _resolveAuthorityAttempt: number = 0;
86+
8287
constructor(
8388
private readonly _extensionsProposedApi: ExtensionsProposedApi,
8489
private readonly _extensionHostFactory: IExtensionHostFactory,
@@ -97,7 +102,8 @@ export abstract class AbstractExtensionService extends Disposable implements IEx
97102
@ILogService protected readonly _logService: ILogService,
98103
@IRemoteAgentService protected readonly _remoteAgentService: IRemoteAgentService,
99104
@IRemoteExtensionsScannerService protected readonly _remoteExtensionsScannerService: IRemoteExtensionsScannerService,
100-
@ILifecycleService private readonly _lifecycleService: ILifecycleService
105+
@ILifecycleService private readonly _lifecycleService: ILifecycleService,
106+
@IRemoteAuthorityResolverService protected readonly _remoteAuthorityResolverService: IRemoteAuthorityResolverService,
101107
) {
102108
super();
103109

@@ -521,6 +527,98 @@ export abstract class AbstractExtensionService extends Disposable implements IEx
521527
this._onDidChangeExtensionsStatus.fire(this._registry.getAllExtensionDescriptions().map(e => e.identifier));
522528
}
523529

530+
//#region remote authority resolving
531+
532+
protected async _resolveAuthorityInitial(remoteAuthority: string): Promise<ResolverResult> {
533+
const MAX_ATTEMPTS = 5;
534+
535+
for (let attempt = 1; ; attempt++) {
536+
try {
537+
return this._resolveAuthorityWithLogging(remoteAuthority);
538+
} catch (err) {
539+
if (RemoteAuthorityResolverError.isNoResolverFound(err)) {
540+
// There is no point in retrying if there is no resolver found
541+
throw err;
542+
}
543+
544+
if (RemoteAuthorityResolverError.isNotAvailable(err)) {
545+
// The resolver is not available and asked us to not retry
546+
throw err;
547+
}
548+
549+
if (attempt >= MAX_ATTEMPTS) {
550+
// Too many failed attempts, give up
551+
throw err;
552+
}
553+
}
554+
}
555+
}
556+
557+
protected async _resolveAuthorityAgain(): Promise<void> {
558+
const remoteAuthority = this._environmentService.remoteAuthority;
559+
if (!remoteAuthority) {
560+
return;
561+
}
562+
563+
this._remoteAuthorityResolverService._clearResolvedAuthority(remoteAuthority);
564+
try {
565+
const result = await this._resolveAuthorityWithLogging(remoteAuthority);
566+
this._remoteAuthorityResolverService._setResolvedAuthority(result.authority, result.options);
567+
} catch (err) {
568+
this._remoteAuthorityResolverService._setResolvedAuthorityError(remoteAuthority, err);
569+
}
570+
}
571+
572+
private async _resolveAuthorityWithLogging(remoteAuthority: string): Promise<ResolverResult> {
573+
const authorityPrefix = getRemoteAuthorityPrefix(remoteAuthority);
574+
const sw = StopWatch.create(false);
575+
this._logService.info(`Invoking resolveAuthority(${authorityPrefix})...`);
576+
try {
577+
performance.mark(`code/willResolveAuthority/${authorityPrefix}`);
578+
const result = await this._resolveAuthority(remoteAuthority);
579+
performance.mark(`code/didResolveAuthorityOK/${authorityPrefix}`);
580+
this._logService.info(`resolveAuthority(${authorityPrefix}) returned '${result.authority.connectTo}' after ${sw.elapsed()} ms`);
581+
return result;
582+
} catch (err) {
583+
performance.mark(`code/didResolveAuthorityError/${authorityPrefix}`);
584+
this._logService.error(`resolveAuthority(${authorityPrefix}) returned an error after ${sw.elapsed()} ms`, err);
585+
throw err;
586+
}
587+
}
588+
589+
protected async _resolveAuthorityOnExtensionHosts(kind: ExtensionHostKind, remoteAuthority: string): Promise<ResolverResult> {
590+
591+
const extensionHosts = this._getExtensionHostManagers(kind);
592+
if (extensionHosts.length === 0) {
593+
// no local process extension hosts
594+
throw new Error(`Cannot resolve authority`);
595+
}
596+
597+
this._resolveAuthorityAttempt++;
598+
const results = await Promise.all(extensionHosts.map(extHost => extHost.resolveAuthority(remoteAuthority, this._resolveAuthorityAttempt)));
599+
600+
let bestErrorResult: IResolveAuthorityErrorResult | null = null;
601+
for (const result of results) {
602+
if (result.type === 'ok') {
603+
return result.value;
604+
}
605+
if (!bestErrorResult) {
606+
bestErrorResult = result;
607+
continue;
608+
}
609+
const bestErrorIsUnknown = (bestErrorResult.error.code === RemoteAuthorityResolverErrorCode.Unknown);
610+
const errorIsUnknown = (result.error.code === RemoteAuthorityResolverErrorCode.Unknown);
611+
if (bestErrorIsUnknown && !errorIsUnknown) {
612+
bestErrorResult = result;
613+
}
614+
}
615+
616+
// we can only reach this if there is an error
617+
throw new RemoteAuthorityResolverError(bestErrorResult!.error.message, bestErrorResult!.error.code, bestErrorResult!.error.detail);
618+
}
619+
620+
//#endregion
621+
524622
//#region Stopping / Starting / Restarting
525623

526624
public stopExtensionHosts(): Promise<boolean>;
@@ -1019,6 +1117,7 @@ export abstract class AbstractExtensionService extends Disposable implements IEx
10191117
protected abstract _resolveExtensions(): Promise<ResolvedExtensions>;
10201118
protected abstract _scanSingleExtension(extension: IExtension): Promise<IExtensionDescription | null>;
10211119
protected abstract _onExtensionHostExit(code: number): void;
1120+
protected abstract _resolveAuthority(remoteAuthority: string): Promise<ResolverResult>;
10221121
}
10231122

10241123
export class ResolvedExtensions {

0 commit comments

Comments
 (0)