Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/src/vs/platform/assignment/common/assignment.ts
3296 views
1
/*---------------------------------------------------------------------------------------------
2
* Copyright (c) Microsoft Corporation. All rights reserved.
3
* Licensed under the MIT License. See License.txt in the project root for license information.
4
*--------------------------------------------------------------------------------------------*/
5
6
import { Event } from '../../../base/common/event.js';
7
import * as platform from '../../../base/common/platform.js';
8
import type { IExperimentationFilterProvider } from 'tas-client-umd';
9
10
export const ASSIGNMENT_STORAGE_KEY = 'VSCode.ABExp.FeatureData';
11
export const ASSIGNMENT_REFETCH_INTERVAL = 60 * 60 * 1000; // 1 hour
12
13
export interface IAssignmentService {
14
readonly _serviceBrand: undefined;
15
16
readonly onDidRefetchAssignments: Event<void>;
17
getTreatment<T extends string | number | boolean>(name: string): Promise<T | undefined>;
18
}
19
20
export enum TargetPopulation {
21
Insiders = 'insider',
22
Public = 'public',
23
Exploration = 'exploration'
24
}
25
26
/*
27
Based upon the official VSCode currently existing filters in the
28
ExP backend for the VSCode cluster.
29
https://experimentation.visualstudio.com/Analysis%20and%20Experimentation/_git/AnE.ExP.TAS.TachyonHost.Configuration?path=%2FConfigurations%2Fvscode%2Fvscode.json&version=GBmaster
30
"X-MSEdge-Market": "detection.market",
31
"X-FD-Corpnet": "detection.corpnet",
32
"X-VSCode-AppVersion": "appversion",
33
"X-VSCode-Build": "build",
34
"X-MSEdge-ClientId": "clientid",
35
"X-VSCode-ExtensionName": "extensionname",
36
"X-VSCode-ExtensionVersion": "extensionversion",
37
"X-VSCode-TargetPopulation": "targetpopulation",
38
"X-VSCode-Language": "language"
39
*/
40
export enum Filters {
41
/**
42
* The market in which the extension is distributed.
43
*/
44
Market = 'X-MSEdge-Market',
45
46
/**
47
* The corporation network.
48
*/
49
CorpNet = 'X-FD-Corpnet',
50
51
/**
52
* Version of the application which uses experimentation service.
53
*/
54
ApplicationVersion = 'X-VSCode-AppVersion',
55
56
/**
57
* Insiders vs Stable.
58
*/
59
Build = 'X-VSCode-Build',
60
61
/**
62
* Client Id which is used as primary unit for the experimentation.
63
*/
64
ClientId = 'X-MSEdge-ClientId',
65
66
/**
67
* Extension header.
68
*/
69
ExtensionName = 'X-VSCode-ExtensionName',
70
71
/**
72
* The version of the extension.
73
*/
74
ExtensionVersion = 'X-VSCode-ExtensionVersion',
75
76
/**
77
* The language in use by VS Code
78
*/
79
Language = 'X-VSCode-Language',
80
81
/**
82
* The target population.
83
* This is used to separate internal, early preview, GA, etc.
84
*/
85
TargetPopulation = 'X-VSCode-TargetPopulation',
86
}
87
88
export class AssignmentFilterProvider implements IExperimentationFilterProvider {
89
constructor(
90
private version: string,
91
private appName: string,
92
private machineId: string,
93
private targetPopulation: TargetPopulation
94
) { }
95
96
/**
97
* Returns a version string that can be parsed by the TAS client.
98
* The tas client cannot handle suffixes lke "-insider"
99
* Ref: https://github.com/microsoft/tas-client/blob/30340d5e1da37c2789049fcf45928b954680606f/vscode-tas-client/src/vscode-tas-client/VSCodeFilterProvider.ts#L35
100
*
101
* @param version Version string to be trimmed.
102
*/
103
private static trimVersionSuffix(version: string): string {
104
const regex = /\-[a-zA-Z0-9]+$/;
105
const result = version.split(regex);
106
107
return result[0];
108
}
109
110
getFilterValue(filter: string): string | null {
111
switch (filter) {
112
case Filters.ApplicationVersion:
113
return AssignmentFilterProvider.trimVersionSuffix(this.version); // productService.version
114
case Filters.Build:
115
return this.appName; // productService.nameLong
116
case Filters.ClientId:
117
return this.machineId;
118
case Filters.Language:
119
return platform.language;
120
case Filters.ExtensionName:
121
return 'vscode-core'; // always return vscode-core for exp service
122
case Filters.ExtensionVersion:
123
return '999999.0'; // always return a very large number for cross-extension experimentation
124
case Filters.TargetPopulation:
125
return this.targetPopulation;
126
default:
127
return '';
128
}
129
}
130
131
getFilters(): Map<string, any> {
132
const filters: Map<string, any> = new Map<string, any>();
133
const filterValues = Object.values(Filters);
134
for (const value of filterValues) {
135
filters.set(value, this.getFilterValue(value));
136
}
137
138
return filters;
139
}
140
}
141
142