Persistent Flags Across Requests

Most feature flag definitions result into the flag being either on or off based on an outside condition such as AlwaysOn/AlwaysOff, TimeWindow and Targetting when at 100%.

Enabling the flag for only a percentage of requests can result in the user having different values between requests, so the state needs to be stored. This is done by implementing the ISessionManager interface.

Persisting flags in the user's Session

public class HttpContextFeatureSessionManager : ISessionManager
{
    private readonly IHttpContextAccessor _contextAccessor;
    private const string SessionKeyPrefix = "feature_flag_";

    public HttpContextFeatureSessionManager(IHttpContextAccessor contextAccessor)
    {
        _contextAccessor = contextAccessor;
    }

    public Task<bool?> GetAsync(string featureName)
    {
        bool keyExistsInHttpSession = _contextAccessor.HttpContext!
                      .Session
                      .TryGetValue(key: $"{SessionKeyPrefix}{featureName}",
                                   value: out byte[]? bytes);

        if (keyExistsInHttpSession)
        {
            return Task.FromResult((bool?)BitConverter.ToBoolean(bytes));
        }

        return Task.FromResult<bool?>(null);
    }

    public Task SetAsync(string featureName, bool enabled)
    {
        _contextAccessor.HttpContext!
                        .Session
                        .Set(key: $"{SessionKeyPrefix}{featureName}",
                             value: BitConverter.GetBytes(enabled));

        return Task.CompletedTask;
    }
}

Then it can be registered in Startup.cs

Persisting flags in Redis

The example below uses a query variable u as a user diferentiator, and caches the values for 30 minutes.

Then it can be registered in Startup.cs

Last updated

Was this helpful?