From c16036705e72024ddea3a313241fcf604de370a8 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Mon, 27 Jun 2022 12:53:24 -0700 Subject: [PATCH] Initial contents for experimentation in typescript-language-features. (#153358) Co-authored-by: Daniel Rosenwasser --- .../typescript-language-features/package.json | 1 + .../src/experimentationService.ts | 93 +++++++++++++++++++ .../typescript-language-features/yarn.lock | 26 ++++++ 3 files changed, 120 insertions(+) create mode 100644 extensions/typescript-language-features/src/experimentationService.ts diff --git a/extensions/typescript-language-features/package.json b/extensions/typescript-language-features/package.json index bf441e4a180..bd15126b55d 100644 --- a/extensions/typescript-language-features/package.json +++ b/extensions/typescript-language-features/package.json @@ -38,6 +38,7 @@ "jsonc-parser": "^2.2.1", "semver": "5.5.1", "vscode-nls": "^5.0.0", + "vscode-tas-client": "^0.1.47", "vscode-uri": "^3.0.3" }, "devDependencies": { diff --git a/extensions/typescript-language-features/src/experimentationService.ts b/extensions/typescript-language-features/src/experimentationService.ts new file mode 100644 index 00000000000..3b24c612c9a --- /dev/null +++ b/extensions/typescript-language-features/src/experimentationService.ts @@ -0,0 +1,93 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import * as vscode from 'vscode'; +import VsCodeTelemetryReporter from '@vscode/extension-telemetry'; +import * as tas from 'vscode-tas-client'; + +interface ExperimentTypes { + // None for now. +} + +export class ExperimentationService implements vscode.Disposable { + private _experimentationServicePromise: Promise; + private _telemetryReporter: ExperimentTelemetryReporter; + + constructor(private readonly _extensionContext: vscode.ExtensionContext) { + this._telemetryReporter = new ExperimentTelemetryReporter(_extensionContext); + this._experimentationServicePromise = this.createExperimentationService(); + } + + public async getTreatmentVariable(name: K, defaultValue: ExperimentTypes[K]): Promise { + const experimentationService = await this._experimentationServicePromise; + try { + const treatmentVariable = experimentationService.getTreatmentVariableAsync('vscode', name, /*checkCache*/ true) as ExperimentTypes[K]; + return treatmentVariable; + } catch { + return defaultValue; + } + } + + private async createExperimentationService(): Promise { + let targetPopulation: tas.TargetPopulation; + switch (vscode.env.uriScheme) { + case 'vscode': + targetPopulation = tas.TargetPopulation.Public; + case 'vscode-insiders': + targetPopulation = tas.TargetPopulation.Insiders; + case 'vscode-exploration': + targetPopulation = tas.TargetPopulation.Internal; + case 'code-oss': + targetPopulation = tas.TargetPopulation.Team; + default: + targetPopulation = tas.TargetPopulation.Public; + } + + const id = this._extensionContext.extension.id; + const version = this._extensionContext.extension.packageJSON.version || ''; + const experimentationService = tas.getExperimentationService(id, version, targetPopulation, this._telemetryReporter, this._extensionContext.globalState); + await experimentationService.initialFetch; + return experimentationService; + } + + + /** + * @inheritdoc + */ + public dispose() { + this._telemetryReporter.dispose(); + } +} + +export class ExperimentTelemetryReporter + implements tas.IExperimentationTelemetry, vscode.Disposable { + private _sharedProperties: Record = {}; + private _reporter: VsCodeTelemetryReporter; + constructor(ctxt: vscode.ExtensionContext) { + const extension = ctxt.extension; + const packageJSON = extension.packageJSON; + this._reporter = new VsCodeTelemetryReporter( + extension.id, + packageJSON.version || '', + packageJSON.aiKey || ''); + + } + + setSharedProperty(name: string, value: string): void { + this._sharedProperties[name] = value; + } + + postEvent(eventName: string, props: Map): void { + const propsObject = { + ...this._sharedProperties, + ...Object.fromEntries(props), + }; + this._reporter.sendTelemetryEvent(eventName, propsObject); + } + + dispose() { + this._reporter.dispose(); + } +} diff --git a/extensions/typescript-language-features/yarn.lock b/extensions/typescript-language-features/yarn.lock index ccf832aca13..9b17075c8c4 100644 --- a/extensions/typescript-language-features/yarn.lock +++ b/extensions/typescript-language-features/yarn.lock @@ -17,6 +17,18 @@ resolved "https://registry.yarnpkg.com/@vscode/extension-telemetry/-/extension-telemetry-0.6.1.tgz#f8d1f7145baf932b75077c48107edff48501fc14" integrity sha512-Y4Oc8yGURGVF4WhCZcu+EVy+MAIeQDLDVeDlLn59H0C1w+7xr8dL2ZtDBioy+Hog1Edrd6zOwr3Na7xe1iC/UA== +axios@^0.26.1: + version "0.26.1" + resolved "https://registry.yarnpkg.com/axios/-/axios-0.26.1.tgz#1ede41c51fcf51bbbd6fd43669caaa4f0495aaa9" + integrity sha512-fPwcX4EvnSHuInCMItEhAGnaSEXRBjtzh9fOtsE6E1G6p7vl7edEeZe11QHf18+6+9gR5PbKV/sGKNaD8YaMeA== + dependencies: + follow-redirects "^1.14.8" + +follow-redirects@^1.14.8: + version "1.15.1" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.1.tgz#0ca6a452306c9b276e4d3127483e29575e207ad5" + integrity sha512-yLAMQs+k0b2m7cVxpS1VKJVvoz7SS9Td1zss3XRwXj+ZDH00RJgnuLx7E44wx02kQLrdM3aOOy+FpzS7+8OizA== + jsonc-parser@^2.2.1: version "2.3.1" resolved "https://registry.yarnpkg.com/jsonc-parser/-/jsonc-parser-2.3.1.tgz#59549150b133f2efacca48fe9ce1ec0659af2342" @@ -27,11 +39,25 @@ semver@5.5.1: resolved "https://registry.yarnpkg.com/semver/-/semver-5.5.1.tgz#7dfdd8814bdb7cabc7be0fb1d734cfb66c940477" integrity sha512-PqpAxfrEhlSUWge8dwIp4tZnQ25DIOthpiaHNIthsjEFQD6EvqUKUDM7L8O2rShkFccYo1VjJR0coWfNkCubRw== +tas-client@0.1.45: + version "0.1.45" + resolved "https://registry.yarnpkg.com/tas-client/-/tas-client-0.1.45.tgz#83bbf73f8458a0f527f9a389f7e1c37f63a64a76" + integrity sha512-IG9UmCpDbDPK23UByQ27rLybkRZYEx2eC9EkieXdwPKKjZPD2zPwfQmyGnZrZet4FUt3yj0ytkwz+liR9Nz/nA== + dependencies: + axios "^0.26.1" + vscode-nls@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/vscode-nls/-/vscode-nls-5.0.0.tgz#99f0da0bd9ea7cda44e565a74c54b1f2bc257840" integrity sha512-u0Lw+IYlgbEJFF6/qAqG2d1jQmJl0eyAGJHoAJqr2HT4M2BNuQYSEiSE75f52pXHSJm8AlTjnLLbBFPrdz2hpA== +vscode-tas-client@^0.1.47: + version "0.1.47" + resolved "https://registry.yarnpkg.com/vscode-tas-client/-/vscode-tas-client-0.1.47.tgz#d66795cbbaa231aba659b6c40d43927d73596375" + integrity sha512-SlEPDi+0gwxor4ANzBtXwqROPQdQkClHeVJgnkvdDF5Xnl407htCsabTPAq4Di8muObORtLchqQS/k1ocaGDEg== + dependencies: + tas-client "0.1.45" + vscode-uri@^3.0.3: version "3.0.3" resolved "https://registry.yarnpkg.com/vscode-uri/-/vscode-uri-3.0.3.tgz#a95c1ce2e6f41b7549f86279d19f47951e4f4d84"