diff --git a/src/Microsoft.FeatureManagement/FeatureManager.cs b/src/Microsoft.FeatureManagement/FeatureManager.cs index 76a30859..677c556a 100644 --- a/src/Microsoft.FeatureManagement/FeatureManager.cs +++ b/src/Microsoft.FeatureManagement/FeatureManager.cs @@ -13,6 +13,7 @@ using System.Collections.Generic; using System.Diagnostics; using System.Linq; +using System.Runtime.CompilerServices; using System.Threading; using System.Threading.Tasks; @@ -145,11 +146,18 @@ private async Task IsEnabledWithVariantsAsync(string feature, TC return isFeatureEnabled; } - public async IAsyncEnumerable GetFeatureNamesAsync() + public IAsyncEnumerable GetFeatureNamesAsync() { - await foreach (FeatureDefinition featureDefintion in _featureDefinitionProvider.GetAllFeatureDefinitionsAsync().ConfigureAwait(false)) + return GetFeatureNamesAsync(CancellationToken.None); + } + + public async IAsyncEnumerable GetFeatureNamesAsync([EnumeratorCancellation] CancellationToken cancellationToken) + { + await foreach (FeatureDefinition featureDefinition in _featureDefinitionProvider.GetAllFeatureDefinitionsAsync().ConfigureAwait(false)) { - yield return featureDefintion.Name; + cancellationToken.ThrowIfCancellationRequested(); + + yield return featureDefinition.Name; } } diff --git a/src/Microsoft.FeatureManagement/FeatureManagerSnapshot.cs b/src/Microsoft.FeatureManagement/FeatureManagerSnapshot.cs index 9e20e8c6..35c4b0ec 100644 --- a/src/Microsoft.FeatureManagement/FeatureManagerSnapshot.cs +++ b/src/Microsoft.FeatureManagement/FeatureManagerSnapshot.cs @@ -5,6 +5,7 @@ using System; using System.Collections.Concurrent; using System.Collections.Generic; +using System.Runtime.CompilerServices; using System.Threading; using System.Threading.Tasks; @@ -15,23 +16,28 @@ namespace Microsoft.FeatureManagement /// class FeatureManagerSnapshot : IFeatureManagerSnapshot, IVariantFeatureManagerSnapshot { - private readonly FeatureManager _featureManager; + private readonly IVariantFeatureManager _featureManager; private readonly ConcurrentDictionary> _flagCache = new ConcurrentDictionary>(); private readonly ConcurrentDictionary _variantCache = new ConcurrentDictionary(); private IEnumerable _featureNames; - public FeatureManagerSnapshot(FeatureManager featureManager) + public FeatureManagerSnapshot(IVariantFeatureManager featureManager) { _featureManager = featureManager ?? throw new ArgumentNullException(nameof(featureManager)); } - public async IAsyncEnumerable GetFeatureNamesAsync() + public IAsyncEnumerable GetFeatureNamesAsync() + { + return GetFeatureNamesAsync(CancellationToken.None); + } + + public async IAsyncEnumerable GetFeatureNamesAsync([EnumeratorCancellation] CancellationToken cancellationToken) { if (_featureNames == null) { var featureNames = new List(); - await foreach (string featureName in _featureManager.GetFeatureNamesAsync().ConfigureAwait(false)) + await foreach (string featureName in _featureManager.GetFeatureNamesAsync(cancellationToken).ConfigureAwait(false)) { featureNames.Add(featureName); } @@ -49,28 +55,28 @@ public Task IsEnabledAsync(string feature) { return _flagCache.GetOrAdd( feature, - (key) => _featureManager.IsEnabledAsync(key)); + (key) => _featureManager.IsEnabledAsync(key, CancellationToken.None)); } public Task IsEnabledAsync(string feature, TContext context) { return _flagCache.GetOrAdd( feature, - (key) => _featureManager.IsEnabledAsync(key, context)); + (key) => _featureManager.IsEnabledAsync(key, context, CancellationToken.None)); } public Task IsEnabledAsync(string feature, CancellationToken cancellationToken) { return _flagCache.GetOrAdd( feature, - (key) => _featureManager.IsEnabledAsync(key)); + (key) => _featureManager.IsEnabledAsync(key, cancellationToken)); } public Task IsEnabledAsync(string feature, TContext context, CancellationToken cancellationToken) { return _flagCache.GetOrAdd( feature, - (key) => _featureManager.IsEnabledAsync(key, context)); + (key) => _featureManager.IsEnabledAsync(key, context, cancellationToken)); } public async ValueTask GetVariantAsync(string feature, CancellationToken cancellationToken) diff --git a/src/Microsoft.FeatureManagement/IVariantFeatureManager.cs b/src/Microsoft.FeatureManagement/IVariantFeatureManager.cs index 10395327..34eea877 100644 --- a/src/Microsoft.FeatureManagement/IVariantFeatureManager.cs +++ b/src/Microsoft.FeatureManagement/IVariantFeatureManager.cs @@ -4,6 +4,7 @@ using System.Threading.Tasks; using System.Threading; using Microsoft.FeatureManagement.FeatureFilters; +using System.Collections.Generic; namespace Microsoft.FeatureManagement { @@ -12,6 +13,12 @@ namespace Microsoft.FeatureManagement /// public interface IVariantFeatureManager { + /// + /// Retrieves a list of feature names registered in the feature manager. + /// + /// An enumerator which provides asynchronous iteration over the feature names registered in the feature manager. + IAsyncEnumerable GetFeatureNamesAsync(CancellationToken cancellationToken); + /// /// Checks whether a given feature is enabled. /// @@ -30,7 +37,7 @@ public interface IVariantFeatureManager Task IsEnabledAsync(string feature, TContext context, CancellationToken cancellationToken); /// - /// Gets the assigned variant for a specfic feature. + /// Gets the assigned variant for a specific feature. /// /// The name of the feature to evaluate. /// The cancellation token to cancel the operation. @@ -38,7 +45,7 @@ public interface IVariantFeatureManager ValueTask GetVariantAsync(string feature, CancellationToken cancellationToken); /// - /// Gets the assigned variant for a specfic feature. + /// Gets the assigned variant for a specific feature. /// /// The name of the feature to evaluate. /// An instance of used to evaluate which variant the user will be assigned.