Skip to content

Commit b747bb4

Browse files
authored
Adds GetFeatureNamesAsync to IVariantFeatureManager and uses the interface in FeatureManagerSnapshot (#270)
1 parent b1b1562 commit b747bb4

File tree

3 files changed

+34
-13
lines changed

3 files changed

+34
-13
lines changed

src/Microsoft.FeatureManagement/FeatureManager.cs

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
using System.Collections.Generic;
1414
using System.Diagnostics;
1515
using System.Linq;
16+
using System.Runtime.CompilerServices;
1617
using System.Threading;
1718
using System.Threading.Tasks;
1819

@@ -145,11 +146,18 @@ private async Task<bool> IsEnabledWithVariantsAsync<TContext>(string feature, TC
145146
return isFeatureEnabled;
146147
}
147148

148-
public async IAsyncEnumerable<string> GetFeatureNamesAsync()
149+
public IAsyncEnumerable<string> GetFeatureNamesAsync()
149150
{
150-
await foreach (FeatureDefinition featureDefintion in _featureDefinitionProvider.GetAllFeatureDefinitionsAsync().ConfigureAwait(false))
151+
return GetFeatureNamesAsync(CancellationToken.None);
152+
}
153+
154+
public async IAsyncEnumerable<string> GetFeatureNamesAsync([EnumeratorCancellation] CancellationToken cancellationToken)
155+
{
156+
await foreach (FeatureDefinition featureDefinition in _featureDefinitionProvider.GetAllFeatureDefinitionsAsync().ConfigureAwait(false))
151157
{
152-
yield return featureDefintion.Name;
158+
cancellationToken.ThrowIfCancellationRequested();
159+
160+
yield return featureDefinition.Name;
153161
}
154162
}
155163

src/Microsoft.FeatureManagement/FeatureManagerSnapshot.cs

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
using System;
66
using System.Collections.Concurrent;
77
using System.Collections.Generic;
8+
using System.Runtime.CompilerServices;
89
using System.Threading;
910
using System.Threading.Tasks;
1011

@@ -15,23 +16,28 @@ namespace Microsoft.FeatureManagement
1516
/// </summary>
1617
class FeatureManagerSnapshot : IFeatureManagerSnapshot, IVariantFeatureManagerSnapshot
1718
{
18-
private readonly FeatureManager _featureManager;
19+
private readonly IVariantFeatureManager _featureManager;
1920
private readonly ConcurrentDictionary<string, Task<bool>> _flagCache = new ConcurrentDictionary<string, Task<bool>>();
2021
private readonly ConcurrentDictionary<string, Variant> _variantCache = new ConcurrentDictionary<string, Variant>();
2122
private IEnumerable<string> _featureNames;
2223

23-
public FeatureManagerSnapshot(FeatureManager featureManager)
24+
public FeatureManagerSnapshot(IVariantFeatureManager featureManager)
2425
{
2526
_featureManager = featureManager ?? throw new ArgumentNullException(nameof(featureManager));
2627
}
2728

28-
public async IAsyncEnumerable<string> GetFeatureNamesAsync()
29+
public IAsyncEnumerable<string> GetFeatureNamesAsync()
30+
{
31+
return GetFeatureNamesAsync(CancellationToken.None);
32+
}
33+
34+
public async IAsyncEnumerable<string> GetFeatureNamesAsync([EnumeratorCancellation] CancellationToken cancellationToken)
2935
{
3036
if (_featureNames == null)
3137
{
3238
var featureNames = new List<string>();
3339

34-
await foreach (string featureName in _featureManager.GetFeatureNamesAsync().ConfigureAwait(false))
40+
await foreach (string featureName in _featureManager.GetFeatureNamesAsync(cancellationToken).ConfigureAwait(false))
3541
{
3642
featureNames.Add(featureName);
3743
}
@@ -49,28 +55,28 @@ public Task<bool> IsEnabledAsync(string feature)
4955
{
5056
return _flagCache.GetOrAdd(
5157
feature,
52-
(key) => _featureManager.IsEnabledAsync(key));
58+
(key) => _featureManager.IsEnabledAsync(key, CancellationToken.None));
5359
}
5460

5561
public Task<bool> IsEnabledAsync<TContext>(string feature, TContext context)
5662
{
5763
return _flagCache.GetOrAdd(
5864
feature,
59-
(key) => _featureManager.IsEnabledAsync(key, context));
65+
(key) => _featureManager.IsEnabledAsync(key, context, CancellationToken.None));
6066
}
6167

6268
public Task<bool> IsEnabledAsync(string feature, CancellationToken cancellationToken)
6369
{
6470
return _flagCache.GetOrAdd(
6571
feature,
66-
(key) => _featureManager.IsEnabledAsync(key));
72+
(key) => _featureManager.IsEnabledAsync(key, cancellationToken));
6773
}
6874

6975
public Task<bool> IsEnabledAsync<TContext>(string feature, TContext context, CancellationToken cancellationToken)
7076
{
7177
return _flagCache.GetOrAdd(
7278
feature,
73-
(key) => _featureManager.IsEnabledAsync(key, context));
79+
(key) => _featureManager.IsEnabledAsync(key, context, cancellationToken));
7480
}
7581

7682
public async ValueTask<Variant> GetVariantAsync(string feature, CancellationToken cancellationToken)

src/Microsoft.FeatureManagement/IVariantFeatureManager.cs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using System.Threading.Tasks;
55
using System.Threading;
66
using Microsoft.FeatureManagement.FeatureFilters;
7+
using System.Collections.Generic;
78

89
namespace Microsoft.FeatureManagement
910
{
@@ -12,6 +13,12 @@ namespace Microsoft.FeatureManagement
1213
/// </summary>
1314
public interface IVariantFeatureManager
1415
{
16+
/// <summary>
17+
/// Retrieves a list of feature names registered in the feature manager.
18+
/// </summary>
19+
/// <returns>An enumerator which provides asynchronous iteration over the feature names registered in the feature manager.</returns>
20+
IAsyncEnumerable<string> GetFeatureNamesAsync(CancellationToken cancellationToken);
21+
1522
/// <summary>
1623
/// Checks whether a given feature is enabled.
1724
/// </summary>
@@ -30,15 +37,15 @@ public interface IVariantFeatureManager
3037
Task<bool> IsEnabledAsync<TContext>(string feature, TContext context, CancellationToken cancellationToken);
3138

3239
/// <summary>
33-
/// Gets the assigned variant for a specfic feature.
40+
/// Gets the assigned variant for a specific feature.
3441
/// </summary>
3542
/// <param name="feature">The name of the feature to evaluate.</param>
3643
/// <param name="cancellationToken">The cancellation token to cancel the operation.</param>
3744
/// <returns>A variant assigned to the user based on the feature's configured allocation.</returns>
3845
ValueTask<Variant> GetVariantAsync(string feature, CancellationToken cancellationToken);
3946

4047
/// <summary>
41-
/// Gets the assigned variant for a specfic feature.
48+
/// Gets the assigned variant for a specific feature.
4249
/// </summary>
4350
/// <param name="feature">The name of the feature to evaluate.</param>
4451
/// <param name="context">An instance of <see cref="TargetingContext"/> used to evaluate which variant the user will be assigned.</param>

0 commit comments

Comments
 (0)