Skip to content

Commit a75688b

Browse files
Fix for slowdown caused by initialfetch (microsoft#16969)
* Fix for slowdown caused by initialfetch * Fix tests * Use in memory cache to hold on to values for a given session. * Revert "Use in memory cache to hold on to values for a given session." This reverts commit 82c62ba. * Comment clarifying not awaiting on initialFetch * Update src/client/common/experiments/service.ts Co-authored-by: Kim-Adeline Miguel <51720070+kimadeline@users.noreply.github.com> Co-authored-by: Kim-Adeline Miguel <51720070+kimadeline@users.noreply.github.com>
1 parent 15a24df commit a75688b

3 files changed

Lines changed: 25 additions & 10 deletions

File tree

news/2 Fixes/16959.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
In experiments service don't always `await` on `initialfetch` which can be slow depending on the network.

src/client/common/experiments/service.ts

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,21 @@ export class ExperimentService implements IExperimentService {
8282
public async activate(): Promise<void> {
8383
if (this.experimentationService) {
8484
await this.experimentationService.initializePromise;
85-
await this.experimentationService.initialFetch;
85+
86+
const experiments = this.globalState.get<{ features: string[] }>(EXP_MEMENTO_KEY, { features: [] });
87+
if (experiments.features.length === 0) {
88+
// Only await on this if we don't have anything in cache.
89+
// This means that we start the session with partial experiment info.
90+
// We accept this as a compromise to avoid delaying startup.
91+
92+
// In the case where we don't wait on this promise. If the experiment info changes,
93+
// those changes will be applied in the next session. This is controlled internally
94+
// in the tas-client via `overrideInMemoryFeatures` value that is passed to
95+
// `getFeaturesAsync`. At the time of writing this comment the value of
96+
// `overrideInMemoryFeatures` was always passed in as `false`. So, the experiment
97+
// states did not change mid way.
98+
await this.experimentationService.initialFetch;
99+
}
86100
}
87101
sendOptInOptOutTelemetry(this._optInto, this._optOutFrom, this.appEnvironment.packageJson);
88102
}
@@ -122,7 +136,7 @@ export class ExperimentService implements IExperimentService {
122136
return undefined;
123137
}
124138

125-
return this.experimentationService.getTreatmentVariableAsync(EXP_CONFIG_ID, experiment, true);
139+
return this.experimentationService.getTreatmentVariable<T>(EXP_CONFIG_ID, experiment);
126140
}
127141

128142
private logExperiments() {

src/test/common/experiments/service.unit.test.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -327,12 +327,12 @@ suite('Experimentation service', () => {
327327

328328
suite('Experiment value retrieval', () => {
329329
const experiment = 'Test Experiment - experiment';
330-
let getTreatmentVariableAsyncStub: sinon.SinonStub;
330+
let getTreatmentVariableStub: sinon.SinonStub;
331331

332332
setup(() => {
333-
getTreatmentVariableAsyncStub = sinon.stub().returns(Promise.resolve('value'));
333+
getTreatmentVariableStub = sinon.stub().returns(Promise.resolve('value'));
334334
sinon.stub(tasClient, 'getExperimentationService').returns(({
335-
getTreatmentVariableAsync: getTreatmentVariableAsyncStub,
335+
getTreatmentVariable: getTreatmentVariableStub,
336336
} as unknown) as tasClient.IExperimentationService);
337337

338338
configureApplicationEnvironment('stable', extensionVersion);
@@ -350,7 +350,7 @@ suite('Experimentation service', () => {
350350
const result = await experimentService.getExperimentValue(experiment);
351351

352352
assert.strictEqual(result, 'value');
353-
sinon.assert.calledOnce(getTreatmentVariableAsyncStub);
353+
sinon.assert.calledOnce(getTreatmentVariableStub);
354354
});
355355

356356
test('If the experiment setting is disabled, getExperimentValue should return undefined', async () => {
@@ -365,7 +365,7 @@ suite('Experimentation service', () => {
365365
const result = await experimentService.getExperimentValue(experiment);
366366

367367
assert.isUndefined(result);
368-
sinon.assert.notCalled(getTreatmentVariableAsyncStub);
368+
sinon.assert.notCalled(getTreatmentVariableStub);
369369
});
370370

371371
test('If the opt-out setting contains "All", getExperimentValue should return undefined', async () => {
@@ -380,10 +380,10 @@ suite('Experimentation service', () => {
380380
const result = await experimentService.getExperimentValue(experiment);
381381

382382
assert.isUndefined(result);
383-
sinon.assert.notCalled(getTreatmentVariableAsyncStub);
383+
sinon.assert.notCalled(getTreatmentVariableStub);
384384
});
385385

386-
test('If the opt-out setting contains the experiment name, igetExperimentValue should return undefined', async () => {
386+
test('If the opt-out setting contains the experiment name, getExperimentValue should return undefined', async () => {
387387
configureSettings(true, [], [experiment]);
388388

389389
const experimentService = new ExperimentService(
@@ -395,7 +395,7 @@ suite('Experimentation service', () => {
395395
const result = await experimentService.getExperimentValue(experiment);
396396

397397
assert.isUndefined(result);
398-
sinon.assert.notCalled(getTreatmentVariableAsyncStub);
398+
sinon.assert.notCalled(getTreatmentVariableStub);
399399
});
400400
});
401401

0 commit comments

Comments
 (0)