microsoft/vscode-react-native

Public

mirrored from https://github.com/microsoft/vscode-react-nativeAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
smoke-actionbar-timeout-assertion

Branches

Tags

  • No tags available.
0Branches0Tags
Go to file
Add file
Code

Clone

HTTPS

Download ZIP

src/extension/services/experimentService/experimentService.ts

151lines · modeblame

88671796RedMickey5 years ago1// Copyright (c) Microsoft Corporation. All rights reserved.
2// Licensed under the MIT license. See LICENSE file in the project root for details.
3
4import * as vscode from "vscode";
ab0238b7RedMickey4 years ago5import { TelemetryHelper } from "../../../common/telemetryHelper";
6import { Telemetry } from "../../../common/telemetry";
7import { ExtensionConfigManager } from "../../extensionConfigManager";
f338085detatanova4 years ago8import { IConfig, retryDownloadConfig } from "../remoteConfigHelper";
09f6024fHeniker4 years ago9import { IExperiment } from "./IExperiment";
88671796RedMickey5 years ago10
11export enum ExperimentStatuses {
12ENABLED = "enabled",
13DISABLED = "disabled",
14FAILED = "failed",
15}
16
f338085detatanova4 years ago17export interface ExperimentConfig extends IConfig {
88671796RedMickey5 years ago18experimentName: string;
19popCoveragePercent: number;
20enabled: boolean;
21}
22
23export interface ExperimentParameters extends ExperimentConfig {
24[key: string]: any;
25extensionId?: string;
26}
27
28export interface ExperimentResult {
29resultStatus: ExperimentStatuses;
30updatedExperimentParameters: ExperimentParameters;
31error?: Error;
32}
33
34export class ExperimentService implements vscode.Disposable {
444ec9f8ConnorQi011 months ago35private static instance: ExperimentService | null;
88671796RedMickey5 years ago36
37private readonly endpointURL: string;
38private downloadedExperimentsConfig: Array<ExperimentConfig> | null;
176f99c8ConnorQi013 months ago39private experimentsInstances!: Map<string, IExperiment>;
88671796RedMickey5 years ago40private downloadConfigRequest: Promise<ExperimentConfig[]>;
41private cancellationTokenSource: vscode.CancellationTokenSource;
42
34472878RedMickey5 years ago43public static create(): ExperimentService {
88671796RedMickey5 years ago44if (!ExperimentService.instance) {
45ExperimentService.instance = new ExperimentService();
46}
47
48return ExperimentService.instance;
49}
50
51public async runExperiments(): Promise<void> {
52if (!this.downloadedExperimentsConfig) {
53this.downloadedExperimentsConfig = await this.downloadConfigRequest;
54this.experimentsInstances = await this.initializeExperimentsInstances();
55}
56
09f6024fHeniker4 years ago57const experimentResults: Array<ExperimentResult> = await Promise.all(
34472878RedMickey5 years ago58this.downloadedExperimentsConfig.map(expConfig => this.executeExperiment(expConfig)),
88671796RedMickey5 years ago59);
60
61this.sendExperimentTelemetry(experimentResults);
62}
63
34472878RedMickey5 years ago64public dispose(): void {
88671796RedMickey5 years ago65this.cancellationTokenSource.cancel();
66this.cancellationTokenSource.dispose();
444ec9f8ConnorQi011 months ago67ExperimentService.instance = null;
88671796RedMickey5 years ago68}
69
70private constructor() {
34472878RedMickey5 years ago71this.endpointURL =
72"https://microsoft.github.io/vscode-react-native/experiments/experimentsConfig.json";
88671796RedMickey5 years ago73this.cancellationTokenSource = new vscode.CancellationTokenSource();
74this.downloadedExperimentsConfig = null;
75
f338085detatanova4 years ago76this.downloadConfigRequest = retryDownloadConfig<ExperimentConfig[]>(
77this.endpointURL,
78this.cancellationTokenSource,
79);
88671796RedMickey5 years ago80}
81
82private async executeExperiment(expConfig: ExperimentConfig): Promise<ExperimentResult> {
09f6024fHeniker4 years ago83const curExperimentParameters = ExtensionConfigManager.config.get(expConfig.experimentName);
84const expInstance = this.experimentsInstances.get(expConfig.experimentName);
88671796RedMickey5 years ago85
86let expResult: ExperimentResult;
87if (expInstance && expConfig.enabled) {
88try {
89expResult = await expInstance.run(expConfig, curExperimentParameters);
155e1318JiglioNero5 years ago90ExtensionConfigManager.config.set(
91expConfig.experimentName,
92expResult.updatedExperimentParameters,
93);
88671796RedMickey5 years ago94} catch (err) {
95expResult = {
96resultStatus: ExperimentStatuses.FAILED,
97updatedExperimentParameters: expConfig,
176f99c8ConnorQi013 months ago98error: err as Error,
88671796RedMickey5 years ago99};
100}
101} else {
102expResult = {
103resultStatus: ExperimentStatuses.DISABLED,
104updatedExperimentParameters: expConfig,
105};
106}
107
108return expResult;
109}
110
111private async initializeExperimentsInstances(): Promise<Map<string, IExperiment>> {
09f6024fHeniker4 years ago112const expInstances = new Map<string, IExperiment>();
88671796RedMickey5 years ago113
114if (this.downloadedExperimentsConfig) {
09f6024fHeniker4 years ago115for (const expConfig of this.downloadedExperimentsConfig) {
88671796RedMickey5 years ago116try {
09f6024fHeniker4 years ago117const expClass = await import(`./experiments/${expConfig.experimentName}`);
34472878RedMickey5 years ago118expInstances.set(expConfig.experimentName, new expClass.default());
88671796RedMickey5 years ago119} catch (err) {
120expConfig.enabled = false;
121}
122}
123}
124
125return expInstances;
126}
127
128private sendExperimentTelemetry(experimentsResults: ExperimentResult[]): void {
129const runExperimentsEvent = TelemetryHelper.createTelemetryEvent("runExperiments");
130
131experimentsResults.forEach(expResult => {
34472878RedMickey5 years ago132if (expResult.resultStatus === ExperimentStatuses.FAILED && expResult.error) {
88671796RedMickey5 years ago133TelemetryHelper.addTelemetryEventErrorProperty(
134runExperimentsEvent,
135expResult.error,
136undefined,
34472878RedMickey5 years ago137`${expResult.updatedExperimentParameters.experimentName}.`,
88671796RedMickey5 years ago138);
139} else {
140TelemetryHelper.addTelemetryEventProperty(
141runExperimentsEvent,
142expResult.updatedExperimentParameters.experimentName,
143expResult.resultStatus,
34472878RedMickey5 years ago144false,
88671796RedMickey5 years ago145);
146}
147});
148
149Telemetry.send(runExperimentsEvent);
150}
151}