Skip to content

Disabled feature flag returns "true" from time to time #616

@tiliev

Description

@tiliev

I have an issue with a disabled feature flag that returns true from time to time.
In our Azure App config I have two flags with the same name:

  • Flag1 with no label and value true
  • Flag1 with environment prod and value false

Sometimes on environment prod I get value true for Flag1.

Our setup:

  • We do not want to load all of the flags with no label. That's why we do options.Select("_").
  • I'm using our feature flag manager inside of singleton class
  • We work with feature flags in appsettings.Development.json when developing locally

Code:

Program.cs

webBuilder.ConfigureAppConfiguration(config =>
{
  var settings = config.Build();
  var azureAppConfig = settings.GetSection("AzureAppConfig").Get<AzureAppConfiguration>() ?? new();
  if (string.IsNullOrWhiteSpace(azureAppConfig.ConnectionString))
      return;
  
  config.AddAzureAppConfiguration(options =>
  {
      options.Select("_");
  
      options
          .Connect(azureAppConfig.ConnectionString)
          .UseFeatureFlags(ffOptions =>
          { 
              ffOptions.Select("Service*", LabelFilter.Null);
              ffOptions.Select("Service*", azureAppConfig.LabelFilter);
          });
  });
});

Startup.cs

public static IServiceCollection AddFeatureFlags(this IServiceCollection services, IConfiguration configuration)
{
    var azureAppConfig = configuration.GetSection("AzureAppConfig").Get<AzureAppConfiguration>() ?? new();
    var enableAzureAppConfig = !string.IsNullOrWhiteSpace(azureAppConfig.ConnectionString);

    if (enableAzureAppConfig)
        services.AddAzureAppConfiguration();
    else
        services.AddSingleton<IConfigurationRefresherProvider, NullConfigurationRefresherProvider>();

    services.AddFeatureManagement();
    
    return services;
}

Usage:

public class FeatureFlagsManager : IFeatureFlagsManager
{
    private readonly IFeatureManager featureManager;
    private readonly IEnumerable<IConfigurationRefresher> refreshers;

    public FeatureFlagsManager(IFeatureManager featureManager, IConfigurationRefresherProvider configurationRefresherProvider)
    {
        this.featureManager = featureManager;
        refreshers = configurationRefresherProvider.Refreshers;
    }

    public async Task<bool> IsEnabledAsync(string feature)
    {
        await RefreshConfiguration();

        return await featureManager.IsEnabledAsync(feature);
    }

    private async Task RefreshConfiguration()
    {
        await Task.WhenAll(refreshers.Select(r => r.RefreshAsync()));
    }
}

Please let us know if you see any issues with our setup.

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions