Centric connect.engage.succeed

Fun with Feature Flags

Geschreven door Arnoud van Bokkem - 13 maart 2018

Arnoud van Bokkem
So, I worked for this large team that was developing a complex system for a customer. Due to various reasons, we were working in several branches at the same time. This obviously resulted in a lot of merging to keep all these branches aligned. It took a lot of time and quite often resulted in merge errors. We were looking for a way to get rid of all those branches. Enter feature flags.

A feature flag (or feature toggle) is basically a way to quickly enable or disable parts of your application. Consider the extra functionality you get from an in-app purchase in a mobile app; this could very well be placed after a feature toggle. The same goes for a part of the application that is only available to the HR department of your company. These are examples of business feature flags, and they usually have a long lifespan.

Another type of feature flag is the release feature flag. These are used during the development process to make sure features that are not finished yet are not exposed to ‘others’. Others could refer to team members who are not working on this particular feature, but also to the end user of the application. These types of feature flags normally have a shorter lifespan: if the feature is successfully implemented and made available to the general public, the flag isn’t needed anymore.

Short example

So, what does it look like to use a feature flag? It could be as simple as an if-statement around a block of code:

The developers that work on the new feature enable the feature and work on the new implementation. The rest of the team disables the feature and therefore keep using the existing implementation.

A more advanced way to use feature flags could be to create a new class that implements the same interface as the original class but using the new implementation. Either class will be instantiated and used, depending on the state of the feature flag:

This way, the developers working on the new feature can work in separate files, thereby minimizing the chance of merge conflicts. The code that uses the implementation can now stay the same, making it easier to clean up the old implementation when it is no longer used:

There are of course other ways to use feature flags. It all depends on the context: the longer a feature flag will exist, the more effort you want to put in, and the more advanced the solution probably will be.

Implementing and configuring the feature flag

Another thing to consider is how to implement the feature flag itself. There are a few tips:

  • Don’t use magic strings to name the flags. No ConfigurationManager.AppSettings[“MyFeatureFlag”]. This is error prone and it’s easy to miss a flag when cleaning up. The compiler certainly will not help you with any typos you make.
  • Make sure you clean up the flags that are not being used anymore. Using release feature flags, especially when using multiple flags at the same time, introduces some technical debt that must be fixed as soon as possible.
  • Separate the flag’s definition from its use. Create some centralized place where the flag and its state are defined, like a factory. It will help with managing the flags in use and with cleaning up unused flags.
  • Do not set a default value. If you forget to configure the state of the flag, don’t let the application assume the correct value; just throw an exception.

Some changes are hard to accomplish in a multi-user environment, even when using feature flags. Spend some time thinking about your approach before implementing feature flags, especially in these scenarios:

  • Implementing a breaking change to the data model. These changes are difficult to roll back, and yet toggling a feature on and off requires just that. You might be able to implement the new data model and change the existing code to work with that. Or this change should be done in a feature branch after all;
  • Implementing a large refactoring that changes a lot of code. Putting all these changes behind toggle points will make the code hard to read and maintain, even for the short period this feature flag needs to exist. You will probably be better off using a feature branch.

You will also need to think about where to configure the state of the feature flag. Common scenarios include:

  • In code. This is very easy to implement, but you do need to recompile and redeploy the application if the flag is toggled;
  • In a configuration file. Again, relatively simple, and you can switch the state of the application at runtime;
  • In a database. This is a bit harder to accomplish, but it offers more flexibility, like toggling the flag runtime, creating a user interface for managing the toggles, or combining the toggles with a membership provider to turn on the new feature for some users. Business feature flags will almost always use this type of configuration, since they relate to groups of users.

There are frameworks available to help with implementing and configuring feature flags, such as the NuGet package FeatureToggle by Jason Roberts. This well documented framework will help you get quickly up to speed.

Feature flags and CI/CD

A great use for feature flags is in a CI/CD environment. Without feature flags, a new feature will typically be developed in a feature branch if it consists of multiple work items. As each work item is finished and checked in, the feature comes a bit closer to completion. Once all the work is done, the feature branch will be merged back to the main development branch and from there start its journey through the build and release pipeline. You need a feature branch to be able to release other work without also releasing a half-finished, non-functioning feature. But merging code has to be done manually, so this feature will not be automatically included in a CI/CD release.

Back to our situation, where we can now develop all code in one and the same branch, using our new feature flags. As soon as a work item gets checked in, it will be built and released through our CI/CD pipeline. As long as the feature flag is not set, the unfinished feature will not be available in the release, even though code from that feature is present. Only when the feature flag is set will the new feature be available in the release.

Conclusion

If you want to get rid of those difficult merges, or you are moving towards a more automated build and release strategy, you might very well benefit from feature flags. If you would like to read more about feature flags, Pete Hodgson has written a nice article about different scenarios for using feature flags and when to use what on Martin Fowler's site: https://martinfowler.com/articles/feature-toggles.html. If you want to see feature flags in action, look at this simple code example: https://github.com/ArnoudBM/FunWithFlags. And start using them yourself. It’ll be fun, I promise.

About Arnoud

Craft Expert Arnoud van Bokkem is part of the .NET team within Craft, the development programme for IT professionals (powered by Centric). If you would like to follow his blog, sign up for Craft updates.


Tags:.NET

     
Schrijf een reactie
  • Captcha image
  • Verzenden