sussudio
Version:
An unofficial VS Code Internal API
83 lines (82 loc) • 4.26 kB
JavaScript
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { getTelemetryLevel } from "../../telemetry/common/telemetryUtils.mjs";
import { AssignmentFilterProvider, ASSIGNMENT_REFETCH_INTERVAL, ASSIGNMENT_STORAGE_KEY, TargetPopulation } from "./assignment.mjs";
export class BaseAssignmentService {
getMachineId;
configurationService;
productService;
telemetry;
keyValueStorage;
_serviceBrand;
tasClient;
networkInitialized = false;
overrideInitDelay;
get experimentsEnabled() {
return true;
}
constructor(getMachineId, configurationService, productService, telemetry, keyValueStorage) {
this.getMachineId = getMachineId;
this.configurationService = configurationService;
this.productService = productService;
this.telemetry = telemetry;
this.keyValueStorage = keyValueStorage;
if (productService.tasConfig && this.experimentsEnabled && getTelemetryLevel(this.configurationService) === 3 /* TelemetryLevel.USAGE */) {
this.tasClient = this.setupTASClient();
}
// For development purposes, configure the delay until tas local tas treatment ovverrides are available
const overrideDelaySetting = this.configurationService.getValue('experiments.overrideDelay');
const overrideDelay = typeof overrideDelaySetting === 'number' ? overrideDelaySetting : 0;
this.overrideInitDelay = new Promise(resolve => setTimeout(resolve, overrideDelay));
}
async getTreatment(name) {
// For development purposes, allow overriding tas assignments to test variants locally.
await this.overrideInitDelay;
const override = this.configurationService.getValue('experiments.override.' + name);
if (override !== undefined) {
return override;
}
if (!this.tasClient) {
return undefined;
}
if (!this.experimentsEnabled) {
return undefined;
}
let result;
const client = await this.tasClient;
// The TAS client is initialized but we need to check if the initial fetch has completed yet
// If it is complete, return a cached value for the treatment
// If not, use the async call with `checkCache: true`. This will allow the module to return a cached value if it is present.
// Otherwise it will await the initial fetch to return the most up to date value.
if (this.networkInitialized) {
result = client.getTreatmentVariable('vscode', name);
}
else {
result = await client.getTreatmentVariableAsync('vscode', name, true);
}
result = client.getTreatmentVariable('vscode', name);
return result;
}
async setupTASClient() {
const targetPopulation = this.productService.quality === 'stable' ? TargetPopulation.Public : TargetPopulation.Insiders;
const machineId = await this.getMachineId();
const filterProvider = new AssignmentFilterProvider(this.productService.version, this.productService.nameLong, machineId, targetPopulation);
const tasConfig = this.productService.tasConfig;
const tasClient = new (await import('tas-client-umd')).ExperimentationService({
filterProviders: [filterProvider],
telemetry: this.telemetry,
storageKey: ASSIGNMENT_STORAGE_KEY,
keyValueStorage: this.keyValueStorage,
featuresTelemetryPropertyName: tasConfig.featuresTelemetryPropertyName,
assignmentContextTelemetryPropertyName: tasConfig.assignmentContextTelemetryPropertyName,
telemetryEventName: tasConfig.telemetryEventName,
endpoint: tasConfig.endpoint,
refetchInterval: ASSIGNMENT_REFETCH_INTERVAL,
});
await tasClient.initializePromise;
tasClient.initialFetch.then(() => this.networkInitialized = true);
return tasClient;
}
}