Skip to content

Commit 74ea9e9

Browse files
Merge pull request #556 from microsoft/zhiyuanliang/fix-snapshot-bug
Fix snapshot cache key bug
1 parent b7ee3a5 commit 74ea9e9

File tree

3 files changed

+75
-2
lines changed

3 files changed

+75
-2
lines changed

src/Microsoft.FeatureManagement/FeatureManagerSnapshot.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ public async ValueTask<Variant> GetVariantAsync(string feature, CancellationToke
103103

104104
//
105105
// First, check local cache
106-
if (_variantCache.ContainsKey(feature))
106+
if (_variantCache.ContainsKey(cacheKey))
107107
{
108108
return _variantCache[cacheKey];
109109
}
@@ -121,7 +121,7 @@ public async ValueTask<Variant> GetVariantAsync(string feature, ITargetingContex
121121

122122
//
123123
// First, check local cache
124-
if (_variantCache.ContainsKey(feature))
124+
if (_variantCache.ContainsKey(cacheKey))
125125
{
126126
return _variantCache[cacheKey];
127127
}

tests/Tests.FeatureManagement/FeatureManagementTest.cs

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -332,6 +332,67 @@ public async Task ThreadSafeSnapshot()
332332
}
333333
}
334334

335+
[Fact]
336+
public async Task ReturnsCachedResultFromSnapshot()
337+
{
338+
IConfiguration config = new ConfigurationBuilder().AddJsonFile("appsettings.json").Build();
339+
340+
var services = new ServiceCollection();
341+
342+
services
343+
.AddSingleton(config)
344+
.AddFeatureManagement()
345+
.AddFeatureFilter<TestFilter>();
346+
347+
ServiceProvider serviceProvider = services.BuildServiceProvider();
348+
349+
IVariantFeatureManager featureManager = serviceProvider.GetRequiredService<IVariantFeatureManager>();
350+
351+
IVariantFeatureManager featureManagerSnapshot = serviceProvider.GetRequiredService<IVariantFeatureManagerSnapshot>();
352+
353+
IEnumerable<IFeatureFilterMetadata> featureFilters = serviceProvider.GetRequiredService<IEnumerable<IFeatureFilterMetadata>>();
354+
355+
TestFilter testFeatureFilter = (TestFilter)featureFilters.First(f => f is TestFilter);
356+
357+
int callCount = 0;
358+
bool filterEnabled = true;
359+
360+
testFeatureFilter.Callback = (evaluationContext) =>
361+
{
362+
callCount++;
363+
return Task.FromResult(filterEnabled);
364+
};
365+
366+
// First evaluation - filter is enabled and should return true
367+
bool result1 = await featureManagerSnapshot.IsEnabledAsync(Features.ConditionalFeature);
368+
Assert.Equal(1, callCount);
369+
Assert.True(result1);
370+
371+
Variant variant1 = await featureManagerSnapshot.GetVariantAsync(Features.ConditionalFeature);
372+
Assert.Equal(2, callCount);
373+
Assert.Equal("DefaultWhenEnabled", variant1.Name);
374+
375+
// "Shut down" the feature filter
376+
filterEnabled = false;
377+
378+
// Second evaluation - should use cached value despite filter being shut down
379+
bool result2 = await featureManagerSnapshot.IsEnabledAsync(Features.ConditionalFeature);
380+
Assert.Equal(2, callCount);
381+
Assert.True(result2);
382+
383+
Variant variant2 = await featureManagerSnapshot.GetVariantAsync(Features.ConditionalFeature);
384+
Assert.Equal(2, callCount);
385+
Assert.Equal("DefaultWhenEnabled", variant2.Name);
386+
387+
bool result3 = await featureManager.IsEnabledAsync(Features.ConditionalFeature);
388+
Assert.Equal(3, callCount);
389+
Assert.False(result3);
390+
391+
Variant variant3 = await featureManager.GetVariantAsync(Features.ConditionalFeature);
392+
Assert.Equal(4, callCount);
393+
Assert.Equal("DefaultWhenDisabled", variant3.Name);
394+
}
395+
335396
[Fact]
336397
public void AddsScopedFeatureManagement()
337398
{

tests/Tests.FeatureManagement/appsettings.json

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,18 @@
2828
}
2929
}
3030
]
31+
},
32+
"variants": [
33+
{
34+
"name": "DefaultWhenEnabled"
35+
},
36+
{
37+
"name": "DefaultWhenDisabled"
38+
}
39+
],
40+
"allocation": {
41+
"default_when_enabled": "DefaultWhenEnabled",
42+
"default_when_disabled": "DefaultWhenDisabled"
3143
}
3244
},
3345
{

0 commit comments

Comments
 (0)