Skip to content

Commit edb1a9b

Browse files
authored
Update telemetry events and exp allocations (microsoft#248035)
1 parent e4d5adb commit edb1a9b

File tree

2 files changed

+51
-26
lines changed

2 files changed

+51
-26
lines changed

src/vs/workbench/contrib/welcomeGettingStarted/browser/gettingStarted.ts

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ import { AccessibilityVerbositySettingId } from '../../accessibility/browser/acc
7373
import { AccessibleViewAction } from '../../accessibility/browser/accessibleViewActions.js';
7474
import { KeybindingLabel } from '../../../../base/browser/ui/keybindingLabel/keybindingLabel.js';
7575
import { ScrollbarVisibility } from '../../../../base/common/scrollable.js';
76+
import { IGettingStartedExperimentService } from './gettingStartedExpService.js';
7677

7778
const SLIDE_TRANSITION_TIME_MS = 250;
7879
const configurationKey = 'workbench.startupEditor';
@@ -190,7 +191,8 @@ export class GettingStartedPage extends EditorPane {
190191
@IHostService private readonly hostService: IHostService,
191192
@IWebviewService private readonly webviewService: IWebviewService,
192193
@IWorkspaceContextService private readonly workspaceContextService: IWorkspaceContextService,
193-
@IAccessibilityService private readonly accessibilityService: IAccessibilityService
194+
@IAccessibilityService private readonly accessibilityService: IAccessibilityService,
195+
@IGettingStartedExperimentService private readonly gettingStartedExperimentService: IGettingStartedExperimentService,
194196
) {
195197

196198
super(GettingStartedPage.ID, group, telemetryService, themeService, storageService);
@@ -959,13 +961,18 @@ export class GettingStartedPage extends EditorPane {
959961
const fistContentBehaviour = daysSinceFirstSession < 1 ? 'openToFirstCategory' : 'index';
960962

961963
if (fistContentBehaviour === 'openToFirstCategory') {
962-
const first = this.gettingStartedCategories.filter(c => !c.when || this.contextService.contextMatchesRules(c.when))[0];
964+
const exp = this.gettingStartedExperimentService.getCurrentExperiment();
965+
const first = exp?.walkthroughId ? this.gettingStartedService.getWalkthrough(exp.walkthroughId) : this.gettingStartedCategories.filter(c => !c.when || this.contextService.contextMatchesRules(c.when))[0];
963966
if (first) {
964967
this.hasScrolledToFirstCategory = true;
965968
this.currentWalkthrough = first;
966969
this.editorInput.selectedCategory = this.currentWalkthrough?.id;
967970
this.editorInput.walkthroughPageTitle = this.currentWalkthrough.walkthroughPageTitle;
968-
this.buildCategorySlide(this.editorInput.selectedCategory, undefined);
971+
if (first.id === NEW_WELCOME_EXPERIENCE) {
972+
this.buildNewCategorySlide(this.editorInput.selectedCategory, undefined);
973+
} else {
974+
this.buildCategorySlide(this.editorInput.selectedCategory, undefined);
975+
}
969976
this.setSlide('details', true /* firstLaunch */);
970977
return;
971978
}
@@ -1410,6 +1417,7 @@ export class GettingStartedPage extends EditorPane {
14101417

14111418

14121419
private selectStepByIndex(newIndex: number, steps: IResolvedWalkthroughStep[], direction: number) {
1420+
this.telemetryService.publicLog2<GettingStartedActionEvent, GettingStartedActionClassification>('gettingStarted.ActionExecuted', { command: 'selectTask', argument: steps[newIndex].id, walkthroughId: this.currentWalkthrough?.id });
14131421
const currentIndex = steps.findIndex(step => step.id === this.editorInput.selectedStep);
14141422

14151423
// Update the selected step and build its media
@@ -1756,6 +1764,7 @@ export class GettingStartedPage extends EditorPane {
17561764
}
17571765

17581766
private selectSubStep(selectedStepId: string) {
1767+
this.telemetryService.publicLog2<GettingStartedActionEvent, GettingStartedActionClassification>('gettingStarted.ActionExecuted', { command: 'selectTask', argument: selectedStepId, walkthroughId: this.currentWalkthrough?.id });
17591768
if (this.editorInput.selectedStep === selectedStepId) {
17601769
return;
17611770
}

src/vs/workbench/contrib/welcomeGettingStarted/browser/gettingStartedExpService.ts

Lines changed: 39 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,15 @@ import { IProductService } from '../../../../platform/product/common/productServ
1313
export interface IGettingStartedExperiment {
1414
cohort: number;
1515
experimentGroup: string;
16+
walkthroughId: string;
17+
iteration: number;
1618
}
1719

1820
export const IGettingStartedExperimentService = createDecorator<IGettingStartedExperimentService>('gettingStartedExperimentService');
1921

2022
export interface IGettingStartedExperimentService {
2123
readonly _serviceBrand: undefined;
22-
getCurrentExperiment(): IGettingStartedExperiment;
24+
getCurrentExperiment(): IGettingStartedExperiment | undefined;
2325
}
2426

2527
const EXPERIMENT_STORAGE_KEY = 'gettingStartedExperiment';
@@ -28,33 +30,34 @@ interface ExperimentGroupDefinition {
2830
name: string;
2931
min: number;
3032
max: number;
33+
iteration: number;
34+
walkthroughId: string;
3135
}
3236

3337
export enum GettingStartedExperimentGroup {
3438
New = 'newExp',
39+
Control = 'controlExp',
3540
Default = 'defaultExp'
3641
}
3742

3843
const STABLE_EXPERIMENT_GROUPS: ExperimentGroupDefinition[] = [
39-
// { name: GettingStartedExperimentGroup.New, min: 0.0, max: 0.1 },
40-
//{ name: GettingStartedExperimentGroup.Default, min: 0.1, max: 1.0 }
41-
{ name: GettingStartedExperimentGroup.Default, min: 0.0, max: 1.0 }
44+
// Bump the iteration each time we change group allocations
45+
{ name: GettingStartedExperimentGroup.New, min: 0.0, max: 0.1, iteration: 1, walkthroughId: 'NewWelcomeExperience' },
46+
{ name: GettingStartedExperimentGroup.Control, min: 0.1, max: 0.2, iteration: 1, walkthroughId: 'Setup' },
47+
{ name: GettingStartedExperimentGroup.Default, min: 0.2, max: 1, iteration: 1, walkthroughId: 'Setup' }
4248
];
4349

4450
const INSIDERS_EXPERIMENT_GROUPS: ExperimentGroupDefinition[] = [
45-
// { name: GettingStartedExperimentGroup.New, min: 0.0, max: 0.3 },
46-
//{ name: GettingStartedExperimentGroup.Default, min: 0.3, max: 1.0 }
47-
{ name: GettingStartedExperimentGroup.Default, min: 0.0, max: 1.0 }
48-
];
49-
50-
const DEFAULT_EXPERIMENT_GROUPS: ExperimentGroupDefinition[] = [
51-
{ name: GettingStartedExperimentGroup.Default, min: 0.0, max: 1.0 }
51+
// Bump the iteration each time we change group allocations
52+
{ name: GettingStartedExperimentGroup.New, min: 0.0, max: 0.3, iteration: 1, walkthroughId: 'NewWelcomeExperience' },
53+
{ name: GettingStartedExperimentGroup.Control, min: 0.3, max: 0.6, iteration: 1, walkthroughId: 'Setup' },
54+
{ name: GettingStartedExperimentGroup.Default, min: 0.6, max: 1, iteration: 1, walkthroughId: 'Setup' }
5255
];
5356

5457
export class GettingStartedExperimentService extends Disposable implements IGettingStartedExperimentService {
5558
declare readonly _serviceBrand: undefined;
5659

57-
private readonly experiment: IGettingStartedExperiment;
60+
private readonly experiment: IGettingStartedExperiment | undefined;
5861

5962
constructor(
6063
@IStorageService private readonly storageService: IStorageService,
@@ -66,18 +69,17 @@ export class GettingStartedExperimentService extends Disposable implements IGett
6669
this.sendExperimentTelemetry();
6770
}
6871

69-
private getExperimentAllocation(): ExperimentGroupDefinition[] {
72+
private getExperimentAllocation(): ExperimentGroupDefinition[] | undefined {
7073
const quality = this.productService.quality;
7174
if (quality === 'stable') {
7275
return STABLE_EXPERIMENT_GROUPS;
7376
} else if (quality === 'insider') {
7477
return INSIDERS_EXPERIMENT_GROUPS;
75-
} else {
76-
return DEFAULT_EXPERIMENT_GROUPS;
7778
}
79+
return;
7880
}
7981

80-
private getOrCreateExperiment(): IGettingStartedExperiment {
82+
private getOrCreateExperiment(): IGettingStartedExperiment | undefined {
8183
const storedExperiment = this.storageService.get(EXPERIMENT_STORAGE_KEY, StorageScope.APPLICATION);
8284
if (storedExperiment) {
8385
try {
@@ -88,6 +90,9 @@ export class GettingStartedExperimentService extends Disposable implements IGett
8890
}
8991

9092
const newExperiment = this.createNewExperiment();
93+
if (!newExperiment) {
94+
return;
95+
}
9196

9297
this.storageService.store(
9398
EXPERIMENT_STORAGE_KEY,
@@ -99,44 +104,55 @@ export class GettingStartedExperimentService extends Disposable implements IGett
99104
return newExperiment;
100105
}
101106

102-
private createNewExperiment(): IGettingStartedExperiment {
107+
private createNewExperiment(): IGettingStartedExperiment | undefined {
103108
const cohort = Math.random();
104109
const experimentGroups = this.getExperimentAllocation();
110+
if (!experimentGroups) {
111+
return;
112+
}
105113

106-
let experimentGroup = GettingStartedExperimentGroup.Default;
107114
for (const group of experimentGroups) {
108115
if (cohort >= group.min && cohort < group.max) {
109-
experimentGroup = group.name as GettingStartedExperimentGroup;
110-
break;
116+
return { cohort, experimentGroup: group.name, walkthroughId: group.walkthroughId, iteration: group.iteration };
111117
}
112118
}
113119

114-
return { cohort, experimentGroup };
120+
return;
115121
}
116122

117123
private sendExperimentTelemetry(): void {
124+
if (!this.experiment) {
125+
return;
126+
}
127+
118128
type GettingStartedExperimentClassification = {
119129
owner: 'bhavyaus';
120130
comment: 'Records which experiment cohort the user is in for getting started experience';
121131
cohort: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; comment: 'The exact cohort number for the user' };
122132
experimentGroup: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; comment: 'The experiment group the user is in' };
133+
iteration: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; comment: 'The iteration number for the experiment' };
134+
walkthroughId: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; comment: 'The walkthrough ID for the experiment' };
123135
};
124136

125137
type GettingStartedExperimentEvent = {
126138
cohort: number;
127139
experimentGroup: string;
140+
iteration: number;
141+
walkthroughId: string;
128142
};
129143

130144
this.telemetryService.publicLog2<GettingStartedExperimentEvent, GettingStartedExperimentClassification>(
131145
'gettingStarted.experimentCohort',
132146
{
133147
cohort: this.experiment.cohort,
134-
experimentGroup: this.experiment.experimentGroup
148+
experimentGroup: this.experiment.experimentGroup,
149+
iteration: this.experiment.iteration,
150+
walkthroughId: this.experiment.walkthroughId
135151
}
136152
);
137153
}
138154

139-
getCurrentExperiment(): IGettingStartedExperiment {
155+
getCurrentExperiment(): IGettingStartedExperiment | undefined {
140156
return this.experiment;
141157
}
142158
}

0 commit comments

Comments
 (0)