Skip to content

Added capability to cache filter and assignment parameters. #180

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed

Conversation

jimmyca15
Copy link
Member

@jimmyca15 jimmyca15 commented May 23, 2022

This PR adds a filter parameters binder interface to allow feature manager to cache bound feature filter and feature variant assignment parameters for performance optimization.

Why

Feature filters are given filter parameters in the form of IConfiguration that instruct them how to perform feature evaluation. Often these parameters are bound to a strongly typed settings object before use. Observed cost of binding IConfiguration to perform feature evaluation is high. By caching the result of the binding, a noticeable performance increase can be achieved. This PR gives Implementers of IFeatureFilter and IFeatureVariantAssigner the option to take cache these settings with the help of the feature management system. This is possible through the IFilterParametersBinder and IAssignmentParametersBinder interfaces.

/// <summary>
/// An interface used by the feature management system to pre-bind feature filter parameters to a settings type.
/// <see cref="IFeatureFilter"/>s can implement this interface to take advantage of caching of settings by the feature management system.
/// </summary>
public interface IFilterParametersBinder
{
    /// <summary>
    /// Binds a set of feature filter parameters to a settings object.
    /// </summary>
    /// <param name="parameters">The configuration representing filter parameters to bind to a settings object</param>
    /// <returns>A settings object that is understood by the implementer of <see cref="IFilterParametersBinder"/>.</returns>
    object BindParameters(IConfiguration parameters);
}

Example Usage

class MyFilter : IFeatureFilter, IFilterParametersBinder
{
    public object BindParameters(IConfiguration filterParameters)
    {
        //
        // Called before evaluation occurs, only if settings are not already in cache.
        return filterParameters.Get<FilterSettings>();
    }

    public Task<bool> EvaluateAsync(FeatureFilterEvaluationContext context, CancellationToken cancellationToken)
    {
        //
        // Get pre-bound/cached settings
        FilterSettings settings = (FilterSettings)context.Settings;

        //
        // Use them for evaluation
        ...
    }
}

Breaking Change

This PR introduces a possible breaking change for custom feature definition providers that implement IFeatureFlagDefinitionProvider or IDynamicFeatureDefinitionProvider. To ensure that any filters that implement IFilterParametersBinder see updates to feature filter parameters or feature variant assignment parameters when they are changed, definition providers should ensure a new object reference is used for the parameters in the feature definition. Otherwise, the filters will continue to use the same settings from the cache.

Perf

Rough performance assessment showed improvements of ~100 times at least for complex settings objects.

jimmyca15 added 2 commits June 3, 2022 13:56
…cache bound feature filter and feature variant assignment parameters for performance optimization.
@jimmyca15 jimmyca15 force-pushed the user/jimmyca/settingsCaching branch from 5f21a7c to 8cef284 Compare June 3, 2022 21:07
@dwrpayne
Copy link

I have run into what I believe is this performance problem in a project of mine. My profiles show relatively high CPU cost spent in FeatureManager.IsEnabledAsync(). 90% of that time is spent inside ConfigurationBinder.BindInstance().

We are using FeatureManagement 2.5.1. Is there a plan to merge this PR at some point, or is there a workaround for this issue?

@rossgrambo
Copy link
Contributor

Hello @dwrpayne,

I'm working now on a replacement PR for this one that adds the caching functionality. This PR was built with dynamic features (which don't exist in version 2 of the library) so it's not in a good state to merge currently.

I'll close this PR in favor of mine, once it's up.

@rossgrambo
Copy link
Contributor

Closing in favor of #229

@rossgrambo rossgrambo closed this Apr 24, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants