Giter VIP home page Giter VIP logo

microsoft / featureflightingmanagement Goto Github PK

View Code? Open in Web Editor NEW
38.0 7.0 18.0 1.79 MB

Feature flighting in an Enterprise application allows you release your features in a controlled fashion using feature flags (aka feature toggles). The feature flighting service allows you to manage feature toggles/flags for your application. The service is built on top of Azure App Configuration and offers additional capabilities like Ring rollouts, customized operations, integration with Microsoft Graph and HTTP-based integration.

License: MIT License

TypeScript 0.66% C# 99.34%
feature-flags feature-toggles feature-toggling feature-toggle-service azure-app-configuration flighting azure feature-flight

featureflightingmanagement's Issues

Improve Azure Feature Management processing time by optimizing the feature flag structure stored in Azure App Configuration

The feature flag structure stored in Azure App Configuration contains multiple unnecessary filters. When evaluating a feature flag, all filters in the flag are executed by the Azure FeatureManagement SDK until one of the filter is found to be true. This entails processing a lot of unnecessary filters to evaluate the feature flag.

Store an optimized version of the feature flag in Azure App Configuration. Remove all unnecessary filters and keep only active filters for processing.

Unnecessary Filters

  • To support Ring-based deployments, a feature flag at any time can contain multiple Rings which maybe in inactive state. Each Ring can contain multiple filters, and all filters in the inactive rings are inactive.
  • 2 or more filters of the same filter type can be present in an active ring. For e.g. UserUPN equals '[email protected]' and UserUPN equals '[email protected]'. Such filters can combined into a single filter UserUPN in '[email protected],[email protected]'.

Original Feature Flag
The structure of the original feature flag must be kept intact, hence a secondary storage unit is required to keep the original feature flag structure for reference.

Detailed documenation

Repository needs detailed documentation about the following

  • API reference
  • Usage of BRE
  • Business context behind feature flighting
  • Azure deployment process
  • Code setup process

Mechanism to test rule engines with custom operators

Is your feature request related to a problem? Please describe.
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]

Describe the solution you'd like
A clear and concise description of what you want to happen.

Describe alternatives you've considered
A clear and concise description of any alternative solutions or features you've considered.

Additional context
Add any other context or screenshots about the feature request here.

Performance issues

Flakey performance has been observed in the Evaluate API.

Expected behavior
Evaluate API should respond within 3 seconds for 100 flags concurrently

More details to follow

Notification for prolonged deactivated flags

Partners can configure change notifications for the following scenarios

  • Feature flag 'enabled for all' for more than 'x' days
  • Feature flag disabled for more than 'x' days
  • Feature flag deactivated for more than 'x' days
  • Feature flag in the same ring for more than 'x' days
  • Feature flag running for more than 'x' days
  • Feature flag not being evaluated for more than 'x' days

Maintain feature flag versions

Attach version to a feature flag. Any change in the feature flag should increment the version. All change notifications should contain this version.

Audit feature flag changes

Maintain audit logs for all changes to feature flags. Record of the following information needs to be present

  • Created On
  • Created by
  • Last Edited On
  • Last Deactivated On
  • Last Modified By

Intermittent failures in PROD due to invalid headers

Some API calls in Production is failing due to disposed HttpContext Request Headers.

EXCEPTION
Unhandled exception occured IFeatureCollection has been disposed. Object name: 'Collection'.

STACK TRACE
Microsoft.FeatureFlighting.Common.AppExceptions.GeneralException:
System.ObjectDisposedException:
at Microsoft.AspNetCore.Http.Features.FeatureReferences1.ThrowContextDisposed (Microsoft.Extensions.Features, Version=6.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60) at Microsoft.AspNetCore.Http.DefaultHttpRequest.get_Headers (Microsoft.AspNetCore.Http, Version=6.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60) at Microsoft.FeatureFlighting.API.Controllers.BaseController.GetHeaderValue (Microsoft.FeatureFlighting.API, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null: D:\a\1\s\FeatureFlightingManagement\src\service\API\Controllers\BaseController.cs:102) at Microsoft.FeatureFlighting.API.Controllers.BaseController.GetHeaders (Microsoft.FeatureFlighting.API, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null: D:\a\1\s\FeatureFlightingManagement\src\service\API\Controllers\BaseController.cs:40) at Microsoft.FeatureFlighting.API.Controllers.FeatureFlagsEvaluationController+<EvaluateFeatureFlag>d__5.MoveNext (Microsoft.FeatureFlighting.API, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null: D:\a\1\s\FeatureFlightingManagement\src\service\API\Controllers\FeatureFlagsEvaluationController.cs:90) at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw (System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e) at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e) at System.Runtime.CompilerServices.TaskAwaiter1.GetResult (System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e)
at Microsoft.FeatureFlighting.API.Controllers.FeatureFlagsEvaluationController+<EvaluateFeatureFlag_Backward>d__4.MoveNext (Microsoft.FeatureFlighting.API, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null: D:\a\1\s\FeatureFlightingManagement\src\service\API\Controllers\FeatureFlagsEvaluationController.cs:66)
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw (System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e)
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e)
at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor+TaskOfIActionResultExecutor+d__0.MoveNext (Microsoft.AspNetCore.Mvc.Core, Version=6.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60)
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw (System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e)
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker+<g__Logged|12_1>d.MoveNext (Microsoft.AspNetCore.Mvc.Core, Version=6.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60)
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw (System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e)
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker+<g__Awaited|10_0>d.MoveNext (Microsoft.AspNetCore.Mvc.Core, Version=6.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60)
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw (System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow (Microsoft.AspNetCore.Mvc.Core, Version=6.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next (Microsoft.AspNetCore.Mvc.Core, Version=6.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeInnerFilterAsync (Microsoft.AspNetCore.Mvc.Core, Version=6.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60)
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw (System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e)
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker+<g__Awaited|25_0>d.MoveNext (Microsoft.AspNetCore.Mvc.Core, Version=6.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60)
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw (System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow (Microsoft.AspNetCore.Mvc.Core, Version=6.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Next (Microsoft.AspNetCore.Mvc.Core, Version=6.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.InvokeFilterPipelineAsync (Microsoft.AspNetCore.Mvc.Core, Version=6.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60)
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw (System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e)
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker+<g__Logged|17_1>d.MoveNext (Microsoft.AspNetCore.Mvc.Core, Version=6.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60)
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw (System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker+<g__Logged|17_1>d.MoveNext (Microsoft.AspNetCore.Mvc.Core, Version=6.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60)
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw (System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e)
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e)
at Microsoft.AspNetCore.Routing.EndpointMiddleware+<g__AwaitRequestTask|6_0>d.MoveNext (Microsoft.AspNetCore.Routing, Version=6.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60)
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw (System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e)
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e)
at Microsoft.AspNetCore.Authorization.Policy.AuthorizationMiddlewareResultHandler+d__0.MoveNext (Microsoft.AspNetCore.Authorization.Policy, Version=6.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60)
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw (System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e)
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e)
at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware+d__6.MoveNext (Microsoft.AspNetCore.Authorization.Policy, Version=6.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60)
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw (System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e)
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e)
at Microsoft.Azure.AppConfiguration.AspNetCore.AzureAppConfigurationRefreshMiddleware+d__5.MoveNext (Microsoft.Azure.AppConfiguration.AspNetCore, Version=4.5.1.0, Culture=neutral, PublicKeyToken=69dad7634abb75e4)
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw (System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e)
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e)
at AppInsights.EnterpriseTelemetry.Web.Extension.Middlewares.ExceptionMiddleware+d__7.MoveNext (AppInsights.EnterpriseTelemetry.AspNetCore.Extension, Version=6.0.0.0, Culture=neutral, PublicKeyToken=null)

[Feature Flighting Management] Enable incremental rings

Current State
Rings in Feature Flighting service are exclusive and only a single ring can be activated at the same time

Expected State
Allow partners an option to create incremental rings where a higher ring would encompass the users/conditions enabled in the lower rings

Reason
In most of the cases features are incrementally rolled out to users using Rings. A ring promotion generally implies that the feature is being rolled out to a super set of users. By this definition a higher ring will contain all users to whom the feature has already been rolled out (lower rings) plus a new set of users.
Since, in the current system, Rings are mutually exclusive partners are forced to copy the conditions from the lower rings when creating higher rings. With the concept of incremental ring, partners will need to configure the delta in each ring, since the lower ring conditions would be evaluated as well.

Acceptance Criteria

  • Partners can enable incremental rings on a feature flag level
  • For incremental rings, conditions in the current active ring plus the conditions in all the lower rings should be evaluated
    E.g. if Stage 2 is active, then Stage 0, 1 and 2 must also be evaluated
  • Partners should have the option to disable incremental rings to make the rings mutually exclusive

High CPU utilization spikes causing Performance duress

Under heavy load, Flighting Management App Service is showing spikes in CPU utilization.

Steps to reproduce the behavior:

  1. Run a load test of GET Evaluate API
  2. Check the CPU utilization average and max of the App Service

CPU spikes should be limited

Change notifications for feature flag changes

Send change notifications to partners using webhook mechanism. For any state change in the feature flag invoke the webhook configured by the partner team. Partner teams can configure their own URLs. The payload of the webhook will contain all details of the changes made in the feature flag state.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.