microsoft/FeatureManagement-Dotnet

Caching for a custom FeatureDefinitionProvider

Opened this issue ยท 18 comments

I am building a custom FeatureDefinitionProvider and I want to support caching for it, but this interface IFeatureDefinitionProviderCacheable is internal; would you please change it to be public?

Why don't you implement a configuration provider to fetch you feature flag definitions, that way the config layer would act as the caching?

I am using the same way as tests/Tests.FeatureManagement/InMemoryFeatureDefinitionProvider.cs, in either way, I need IFeatureDefinitionProviderCacheable to be public to use the caching as ConfigurationFeatureDefinitionProvider depends on IFeatureDefinitionProviderCacheable to support caching

You shouldn't need to add that interface to your provider given it is simply to alter handling for test cases and is not needed in actual use case. Please try it without and also what i would be doing is, implementing your provider as a configuration provider that way you definitions are immediately cached for the library to use.

@tahazayed Indeed this functionality should be available to you.

@rossgrambo this conversation mentions a plan to open up this functionality and to file an issue. Are we tracking it?

No, I don't believe it was ever tracked. I'll treat this as the tracking task and look into it.

@jimmyca15 , @rossgrambo Thank you. In my circumstances, the alternative SaaS dynamic feature management costs $20,000 per month.

Hey @tahazayed, thanks for letting us know. I want to align on our different caching to ensure you're getting the caching you want.

IFeatureDefinitionProviderCacheable is an interface that enables a specific cache. This cache is for the binding of IConfiguration to a specific class. For our TimeWindowFilter- this cache prevents IConfiguration.Get() from firing too much, as this type conversion is expensive a few ms, and can be reduced to roughly ~1/100th of the time with this cache.

Separately, there's the more common caching concern- Feature Flags from a server being supplied to the Feature Management library. FeatureManagement reads flags though the IFeatureDefinitionProvider injected dependency. FeatureManagement does not handle caching in this way, instead, it will always request feature definitions directly from the provider. The provider is in charge of caching or to pull from a cache. The provided ConfigurationFeatureDefinitionProvider pulls from IConfiguration, which is essentially our cache for the flag data. Our server provider (Azure App Configuration's .NET Provider), updates the Configuration in order to dynamically update flags. This is what @thompson-tomo was referring to when they said the "config layer would act as the caching".

Being described like this, @tahazayed, which caching were you hoping to take advantage of?

I'll work on making IFeatureDefinitionProviderCacheable public / opening up that performance gain caching either way, but I don't want you to wait on it if it's not the cache you care about.

Thank you for letting me know. I think I want to use what @thompson-tomo is referring to. Do you have an example of how to inject a custom configuration definition provider?

@tahazayed easiest way i have found is to follow the example from Microsoft: https://learn.microsoft.com/en-us/dotnet/core/extensions/custom-configuration-provider and look at some of the samples around.

I wonder where the cache configuration is and when it became invalid, as it seems after implementation, the cache lasts forever

configuration never expires, it is up to the configuration provider to implement an update/expiration mechanism

What is the value of using it (other than modularity)? I get the same result as using AppSettings.json

Value of using a custom configuration provider? Benefit is you can source your feature flags from an external system with the config provider doing the transformation to a dictionary hence making it usable.

I can achieve the same with a custom FeatureDefinitionProvider as I have to implement a cachig with expiration myself anyway,
Also, if I use a configuration provider, I have to hide a property called "Data" from the base class ConfigurationProvider to get the caching work

would work it work for you to simply periodically reload your config after an interval has elapsed? From memory this is what Azure does and can all be achieved by your custom config provider.

It is more complex than FeatureDefinitionProvider as per the proposed solution I have to build a background job and keep it running with a timer to reload the configuration.
Thank you anyway

I have tried it; I had to write three classes instead of one.