mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-12 02:58:31 -05:00
Merge from vscode a348d103d1256a06a2c9b3f9b406298a9fef6898 (#15681)
* Merge from vscode a348d103d1256a06a2c9b3f9b406298a9fef6898 * Fixes and cleanup * Distro * Fix hygiene yarn * delete no yarn lock changes file * Fix hygiene * Fix layer check * Fix CI * Skip lib checks * Remove tests deleted in vs code * Fix tests * Distro * Fix tests and add removed extension point * Skip failing notebook tests for now * Disable broken tests and cleanup build folder * Update yarn.lock and fix smoke tests * Bump sqlite * fix contributed actions and file spacing * Fix user data path * Update yarn.locks Co-authored-by: ADS Merger <karlb@microsoft.com>
This commit is contained in:
@@ -11,7 +11,7 @@ import { IStorageService, StorageScope, StorageTarget } from 'vs/platform/storag
|
||||
import { ITelemetryData } from 'vs/base/common/actions';
|
||||
import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
import product from 'vs/platform/product/common/product';
|
||||
import { IProductService } from 'vs/platform/product/common/productService';
|
||||
|
||||
export const ITASExperimentService = createDecorator<ITASExperimentService>('TASExperimentService');
|
||||
|
||||
@@ -25,7 +25,10 @@ const storageKey = 'VSCode.ABExp.FeatureData';
|
||||
const refetchInterval = 0; // no polling
|
||||
|
||||
class MementoKeyValueStorage implements IKeyValueStorage {
|
||||
constructor(private mementoObj: MementoObject) { }
|
||||
private mementoObj: MementoObject;
|
||||
constructor(private memento: Memento) {
|
||||
this.mementoObj = memento.getMemento(StorageScope.GLOBAL, StorageTarget.MACHINE);
|
||||
}
|
||||
|
||||
async getValue<T>(key: string, defaultValue?: T | undefined): Promise<T | undefined> {
|
||||
const value = await this.mementoObj[key];
|
||||
@@ -34,12 +37,16 @@ class MementoKeyValueStorage implements IKeyValueStorage {
|
||||
|
||||
setValue<T>(key: string, value: T): void {
|
||||
this.mementoObj[key] = value;
|
||||
this.memento.saveMemento();
|
||||
}
|
||||
}
|
||||
|
||||
class ExperimentServiceTelemetry implements IExperimentationTelemetry {
|
||||
private _lastAssignmentContext: string | undefined;
|
||||
constructor(private telemetryService: ITelemetryService) { }
|
||||
constructor(
|
||||
private telemetryService: ITelemetryService,
|
||||
private productService: IProductService
|
||||
) { }
|
||||
|
||||
get assignmentContext(): string[] | undefined {
|
||||
return this._lastAssignmentContext?.split(';');
|
||||
@@ -48,7 +55,7 @@ class ExperimentServiceTelemetry implements IExperimentationTelemetry {
|
||||
// __GDPR__COMMON__ "VSCode.ABExp.Features" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" }
|
||||
// __GDPR__COMMON__ "abexp.assignmentcontext" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" }
|
||||
setSharedProperty(name: string, value: string): void {
|
||||
if (name === product.tasConfig?.assignmentContextTelemetryPropertyName) {
|
||||
if (name === this.productService.tasConfig?.assignmentContextTelemetryPropertyName) {
|
||||
this._lastAssignmentContext = value;
|
||||
}
|
||||
|
||||
@@ -177,6 +184,9 @@ export class ExperimentService implements ITASExperimentService {
|
||||
private tasClient: Promise<TASClient> | undefined;
|
||||
private telemetry: ExperimentServiceTelemetry | undefined;
|
||||
private static MEMENTO_ID = 'experiment.service.memento';
|
||||
private networkInitialized = false;
|
||||
|
||||
private overrideInitDelay: Promise<void>;
|
||||
|
||||
private get experimentsEnabled(): boolean {
|
||||
return this.configurationService.getValue('workbench.enableExperiments') === true;
|
||||
@@ -186,14 +196,31 @@ export class ExperimentService implements ITASExperimentService {
|
||||
@ITelemetryService private telemetryService: ITelemetryService,
|
||||
@IStorageService private storageService: IStorageService,
|
||||
@IConfigurationService private configurationService: IConfigurationService,
|
||||
@IProductService private productService: IProductService
|
||||
) {
|
||||
|
||||
if (product.tasConfig && this.experimentsEnabled && this.telemetryService.isOptedIn) {
|
||||
if (productService.tasConfig && this.experimentsEnabled && this.telemetryService.isOptedIn) {
|
||||
this.tasClient = this.setupTASClient();
|
||||
}
|
||||
|
||||
// For development purposes, configure the delay until tas local tas treatment ovverrides are available
|
||||
const overrideDelay = this.configurationService.getValue<number>('experiments.overrideDelay') ?? 0;
|
||||
this.overrideInitDelay = new Promise(resolve => setTimeout(resolve, overrideDelay));
|
||||
}
|
||||
|
||||
async getTreatment<T extends string | number | boolean>(name: string): Promise<T | undefined> {
|
||||
// For development purposes, allow overriding tas assignments to test variants locally.
|
||||
await this.overrideInitDelay;
|
||||
const override = this.configurationService.getValue<T>('experiments.override.' + name);
|
||||
if (override !== undefined) {
|
||||
type TAASClientOverrideTreatmentData = { treatmentName: string; };
|
||||
type TAASClientOverrideTreatmentClassification = { treatmentName: { classification: 'SystemMetaData', purpose: 'PerformanceAndHealth', }; };
|
||||
this.telemetryService.publicLog2<TAASClientOverrideTreatmentData, TAASClientOverrideTreatmentClassification>('tasClientOverrideTreatment', { treatmentName: name, });
|
||||
return override;
|
||||
}
|
||||
|
||||
const startSetup = Date.now();
|
||||
|
||||
if (!this.tasClient) {
|
||||
return undefined;
|
||||
}
|
||||
@@ -202,7 +229,29 @@ export class ExperimentService implements ITASExperimentService {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return (await this.tasClient).getTreatmentVariable<T>('vscode', name);
|
||||
let result: T | undefined;
|
||||
const client = await this.tasClient;
|
||||
if (this.networkInitialized) {
|
||||
result = client.getTreatmentVariable<T>('vscode', name);
|
||||
} else {
|
||||
result = await client.getTreatmentVariableAsync<T>('vscode', name, true);
|
||||
}
|
||||
|
||||
type TAASClientReadTreatmentData = {
|
||||
treatmentName: string;
|
||||
treatmentValue: string;
|
||||
readTime: number;
|
||||
};
|
||||
|
||||
type TAASClientReadTreatmentCalssification = {
|
||||
treatmentValue: { classification: 'SystemMetaData', purpose: 'PerformanceAndHealth', };
|
||||
treatmentName: { classification: 'SystemMetaData', purpose: 'PerformanceAndHealth', };
|
||||
readTime: { classification: 'SystemMetaData', purpose: 'PerformanceAndHealth', isMeasurement: true };
|
||||
};
|
||||
this.telemetryService.publicLog2<TAASClientReadTreatmentData, TAASClientReadTreatmentCalssification>('tasClientReadTreatmentComplete',
|
||||
{ readTime: Date.now() - startSetup, treatmentName: name, treatmentValue: JSON.stringify(result) });
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
async getCurrentExperiments(): Promise<string[] | undefined> {
|
||||
@@ -220,22 +269,22 @@ export class ExperimentService implements ITASExperimentService {
|
||||
}
|
||||
|
||||
private async setupTASClient(): Promise<TASClient> {
|
||||
const startSetup = Date.now();
|
||||
const telemetryInfo = await this.telemetryService.getTelemetryInfo();
|
||||
const targetPopulation = telemetryInfo.msftInternal ? TargetPopulation.Internal : (product.quality === 'stable' ? TargetPopulation.Public : TargetPopulation.Insiders);
|
||||
const targetPopulation = telemetryInfo.msftInternal ? TargetPopulation.Internal : (this.productService.quality === 'stable' ? TargetPopulation.Public : TargetPopulation.Insiders);
|
||||
const machineId = telemetryInfo.machineId;
|
||||
const filterProvider = new ExperimentServiceFilterProvider(
|
||||
product.version,
|
||||
product.nameLong,
|
||||
this.productService.version,
|
||||
this.productService.nameLong,
|
||||
machineId,
|
||||
targetPopulation
|
||||
);
|
||||
|
||||
const memento = new Memento(ExperimentService.MEMENTO_ID, this.storageService);
|
||||
const keyValueStorage = new MementoKeyValueStorage(memento.getMemento(StorageScope.GLOBAL, StorageTarget.MACHINE));
|
||||
const keyValueStorage = new MementoKeyValueStorage(new Memento(ExperimentService.MEMENTO_ID, this.storageService));
|
||||
|
||||
this.telemetry = new ExperimentServiceTelemetry(this.telemetryService);
|
||||
this.telemetry = new ExperimentServiceTelemetry(this.telemetryService, this.productService);
|
||||
|
||||
const tasConfig = product.tasConfig!;
|
||||
const tasConfig = this.productService.tasConfig!;
|
||||
const tasClient = new (await import('tas-client-umd')).ExperimentationService({
|
||||
filterProviders: [filterProvider],
|
||||
telemetry: this.telemetry,
|
||||
@@ -249,9 +298,15 @@ export class ExperimentService implements ITASExperimentService {
|
||||
});
|
||||
|
||||
await tasClient.initializePromise;
|
||||
|
||||
tasClient.initialFetch.then(() => this.networkInitialized = true);
|
||||
|
||||
type TAASClientSetupData = { setupTime: number; };
|
||||
type TAASClientSetupCalssification = { setupTime: { classification: 'SystemMetaData', purpose: 'PerformanceAndHealth', isMeasurement: true }; };
|
||||
this.telemetryService.publicLog2<TAASClientSetupData, TAASClientSetupCalssification>('tasClientSetupComplete', { setupTime: Date.now() - startSetup });
|
||||
|
||||
return tasClient;
|
||||
}
|
||||
}
|
||||
|
||||
registerSingleton(ITASExperimentService, ExperimentService, false);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user