Skip to content

Commit

Permalink
Removes cache timespan as an option, sets a sliding expiration to 5 m…
Browse files Browse the repository at this point in the history
…in and a absolute of 1 day, adds an interface that determines if the parameter cache should be used
  • Loading branch information
rossgrambo committed May 13, 2023
1 parent 20e6b2c commit 576b762
Show file tree
Hide file tree
Showing 6 changed files with 21 additions and 41 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ namespace Microsoft.FeatureManagement
/// <summary>
/// A feature definition provider that pulls feature definitions from the .NET Core <see cref="IConfiguration"/> system.
/// </summary>
sealed class ConfigurationFeatureDefinitionProvider : IFeatureDefinitionProvider, IDisposable
sealed class ConfigurationFeatureDefinitionProvider : IFeatureDefinitionProvider, IDisposable, IFeatureDefinitionProviderCacheable
{
private const string FeatureFiltersSectionName = "EnabledFor";
private const string RequirementTypeKeyword = "RequirementType";
Expand Down
9 changes: 0 additions & 9 deletions src/Microsoft.FeatureManagement/FeatureManagementOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,5 @@ public class FeatureManagementOptions
/// The default value is true.
/// </summary>
public bool IgnoreMissingFeatures { get; set; } = true;

/// <summary>
/// Controls the cache lifetime of settings bound by <see cref="IFilterParametersBinder"/> in the feature management cache.
/// By default, this cache is off, with a ttl of <see cref="TimeSpan.Zero"/>.
/// To enable caching of filter parameters, a non-zero ttl should be provided. A recommendation is five seconds.
/// Increasing the value may cause an observed increase in memory footprint as items live longer.
/// Lowering the value will decrease performance benefits yielded by caching bound parameters.
/// </summary>
public TimeSpan FilterSettingsCacheTtl { get; set; } = TimeSpan.Zero;
}
}
33 changes: 9 additions & 24 deletions src/Microsoft.FeatureManagement/FeatureManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ class FeatureManager : IFeatureManager, IDisposable
private readonly ConcurrentDictionary<string, IFeatureFilterMetadata> _filterMetadataCache;
private readonly ConcurrentDictionary<string, ContextualFeatureFilterEvaluator> _contextualFeatureFilterCache;
private readonly FeatureManagementOptions _options;
private readonly IMemoryCache _cache;
private readonly IMemoryCache _parametersCache;

private class ConfigurationCacheItem
{
Expand All @@ -47,12 +47,8 @@ public FeatureManager(
_logger = loggerFactory.CreateLogger<FeatureManager>();
_filterMetadataCache = new ConcurrentDictionary<string, IFeatureFilterMetadata>();
_contextualFeatureFilterCache = new ConcurrentDictionary<string, ContextualFeatureFilterEvaluator>();
TryValidateOptions(options, out _options);
_cache = new MemoryCache(
new MemoryCacheOptions
{
ExpirationScanFrequency = _options.FilterSettingsCacheTtl
});
_options = options?.Value ?? throw new ArgumentNullException(nameof(options));
_parametersCache = new MemoryCache(new MemoryCacheOptions());
}

public Task<bool> IsEnabledAsync(string feature)
Expand All @@ -75,7 +71,7 @@ public async IAsyncEnumerable<string> GetFeatureNamesAsync()

public void Dispose()
{
_cache.Dispose();
_parametersCache.Dispose();
}

private async Task<bool> IsEnabledAsync<TContext>(string feature, TContext appContext, bool useAppContext)
Expand Down Expand Up @@ -227,14 +223,14 @@ private void BindSettings(IFeatureFilterMetadata filter, FeatureFilterEvaluation

//
// Check if settings already bound from configuration or the parameters have changed
if (!_cache.TryGetValue(context.FeatureName, out cacheItem) ||
if (!_parametersCache.TryGetValue(context.FeatureName, out cacheItem) ||
cacheItem.Parameters != context.Parameters)
{
settings = binder.BindParameters(context.Parameters);

if (_options.FilterSettingsCacheTtl > TimeSpan.Zero)
if (_featureDefinitionProvider is IFeatureDefinitionProviderCacheable)
{
_cache.Set(
_parametersCache.Set(
context.FeatureName,
new ConfigurationCacheItem
{
Expand All @@ -243,7 +239,8 @@ private void BindSettings(IFeatureFilterMetadata filter, FeatureFilterEvaluation
},
new MemoryCacheEntryOptions
{
AbsoluteExpirationRelativeToNow = _options.FilterSettingsCacheTtl
SlidingExpiration = TimeSpan.FromMinutes(5),
AbsoluteExpirationRelativeToNow = TimeSpan.FromDays(1)
});
}
}
Expand Down Expand Up @@ -327,17 +324,5 @@ private ContextualFeatureFilterEvaluator GetContextualFeatureFilter(string filte

return filter;
}

private FeatureManagementOptions TryValidateOptions(IOptions<FeatureManagementOptions> options, out FeatureManagementOptions _options)
{
_options = options?.Value ?? throw new ArgumentNullException(nameof(options));

if (_options.FilterSettingsCacheTtl < TimeSpan.Zero)
{
throw new ArgumentException("FilterSettingsCacheTtl option must be greater than or equal to TimeSpan.Zero.");
}

return _options;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
using System;
using System.Collections.Generic;
using System.Text;

namespace Microsoft.FeatureManagement
{
public interface IFeatureDefinitionProviderCacheable
{
}
}
6 changes: 0 additions & 6 deletions tests/Tests.FeatureManagement/FeatureManagement.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.TestHost;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Configuration.Memory;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.FeatureManagement;
using Microsoft.FeatureManagement.FeatureFilters;
Expand Down Expand Up @@ -876,11 +875,6 @@ public async Task BindsFeatureFlagSettings()
}
});

services.Configure<FeatureManagementOptions>(options =>
{
options.FilterSettingsCacheTtl = TimeSpan.FromSeconds(5);
});

services.AddSingleton<IFeatureDefinitionProvider>(definitionProvider)
.AddSingleton<IConfiguration>(new ConfigurationBuilder().Build())
.AddFeatureManagement()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

namespace Tests.FeatureManagement
{
class InMemoryFeatureDefinitionProvider : IFeatureDefinitionProvider
class InMemoryFeatureDefinitionProvider : IFeatureDefinitionProvider, IFeatureDefinitionProviderCacheable
{
private IEnumerable<FeatureDefinition> _definitions;

Expand Down

0 comments on commit 576b762

Please sign in to comment.