Git Product home page Git Product logo

microsoft / featureflightingmanagement Goto Github PK

View Code? Open in Web Editor NEW
36.0 6.0 16.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 Introduction

Feature Flighting Management System

Feature toggles is a technique using which you can turn "on" or "off" a feature without a complete system deployment. It's a great technique for controlled feature rollout, conducting A/B tests and implementing Canary cohorts. This is a centralized feature flighting management system which leverages Azure App Configuration's Feature Management.

Capabilities

  1. REST APIs for evaluating Feature Flags
  2. Support for multi-tenancy (without additional infrastructure)
  3. Ring-based feature rollout
  4. REST APIs for managing feature flightings (CRUD)
  5. Integration with Graph API for evaluating flags based on Groups

References

Flighting in a nutshell

Feature Flighting Architecture Diagram

Contributing

This project welcomes contributions and suggestions. Most contributions require you to agree to a Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us the rights to use your contribution. For details, visit https://cla.opensource.microsoft.com.

When you submit a pull request, a CLA bot will automatically determine whether you need to provide a CLA and decorate the PR appropriately (e.g., status check, comment). Simply follow the instructions provided by the bot. You will only need to do this once across all repos using our CLA.

This project has adopted the Microsoft Open Source Code of Conduct. For more information see the Code of Conduct FAQ or contact [email protected] with any additional questions or comments.

Trademarks

This project may contain trademarks or logos for projects, products, or services. Authorized use of Microsoft trademarks or logos is subject to and must follow Microsoft's Trademark & Brand Guidelines. Use of Microsoft trademarks or logos in modified versions of this project must not cause confusion or imply Microsoft sponsorship. Any use of third-party trademarks or logos are subject to those third-party's policies.

featureflightingmanagement's People

Contributors

akreddy123 avatar anshima1 avatar arijitmicrosoft avatar deepakparameshms avatar iswar7892 avatar karsub-microsoft avatar microsoft-github-operations[bot] avatar microsoftopensource avatar patrickcode avatar prnikumb avatar rahaskhora avatar v-kwarhad avatar vandanakvs avatar vanessalobo11 avatar vanessalobo211 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

featureflightingmanagement's Issues

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

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.

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

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

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

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.

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.

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.

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

[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

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)

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.