Agile release pattern: Feature-on/off-switch
If you want to release frequently, a problem you may encounter is that some features, even though functionally complete, don’t stand well on their own, but require other features to be valuable to the user. If you want to release the system in this state, you need a way to hide features. A Feature-on/off-switch is a simple idea for dealing with this.
A feature-on/off-switch is some mechanism to hide features from a system. A feature-on/off-switch must be able to remove menu items concerning the feature and also to prevent adventuresome users from accessing the feature. It may be as crude as commenting out code (not recommended!), to enabling the feature based on a complex set of conditions (also not recommended).
I’ve encountered features switches triggered by the following mechanisms:
- A configuration file or configuration database table tells the system whether to turn the feature on or off.
- The feature is turned on for users that have a specific role (typically something like BETA_TESTER)
- The feature is turned on when the system is deployed as /foo-preview, but not when the system is deployed as /foo
- The feature is turned on after a specific date. This may seem weird, but was a potential solution when we were waiting for a release of another system and operations-freeze during summer was in effect.
There are probably many more conditions you may use to trigger a feature-on/off-switch. Maybe some of my readers have good examples?
Comments:
MIke Long - Aug 20, 2010
This reminds me of how the guys at github deploy their features: http://github.com/blog/677-how-we-deploy-new-features
I think this technique has a potential to drag a codebase into C/C++ preprocessor hell, where you spend hours asking yourself “does this code actually run??”
Johannes Brodwall - Aug 20, 2010
Thanks for the example with GitHub. And like you said: You don’t want to go overboard with this approach.
mike long - Aug 20, 2010
Sounds like how the guys at GitHub release features: http://github.com/blog/677-how-we-deploy-new-features
Thomas Ferris Nicolaisen - Aug 20, 2010
This is a great pattern, been using it for a year or so now. We do the database configuration way.
One annoyance is that when your feature cuts across multiple parts of the application, for example a web shop feature “Save shopping cart” (in a webshop app):
- In the log-in routine, last cart should be loaded 2) When logging out, cart should be automatically saved 3) On Shopping cart page, there are the save/load buttons. 4) In the ordering process, the saved cart could be archived/removed.
The annoyance is that the isShoppingCartStorageEnabled method gets scattered around the code-base a few places, also in the frontend (JSP). You can do this cleaner if you can keep the behavior in aspects, filters or interceptors (we haven’t got any good mechanisms for this yet).
The good thing is that if you’re seeking to understand the CartStorage feature, searching for this isShoppingCartStorageEnabled is a good way to find involved code.
[eirikma] - Aug 23, 2010
A related problem is to enable a feature for only some of the users.
In both cases enabling/disabling the feature can also be implemented in some setup- or script code “around” the application. This can seem like a Good Idea (tm), since the switch is only needed temporarily, but MUST BE AVOIDED. The fact that a feature can be turned on or off is itself a feature of the system and should be programmed into the system in a visible way. Otherwise it is very difficult to track down errors and analyze “strange” behavior.
Lars Reed - Aug 27, 2010
I have used this pattern successfully many times.
A slightly esoteric example - developing and testing an entire subsystem before the final decision was made in the parliament - switching the system ON Jan 1 as the decision was made just before christmas….
Some other ways to switch: * Environment variables – $APP_TRACE -gt 0 * Command line – args.contains(“betaTest”) * Presence of a file or directory – exists %TEMP%weirdMode.txt
[Frisian] - Feb 27, 2013
Works nicely for simple features. But I have yet to find someone to explain to me how to keep it simple, when database schema changes are involved or when the feature has to be called from e.g. an external scheduler. Things will quickly turn messy and complex then. Nowadays using a feature branch in a version control system isn’t rocket science anymore (not even in Subversion), so I consider a feature-on/off switch to be complementary
Johannes Brodwall - Feb 27, 2013
I’ve only used feature toggle for trivial changes myself. On the other hand, I prefer most changes in system to be a series of trivial changes. In the case of the external scheduler, the scheduler itself is the feature toggle.
When it comes to feature branches, I don’t think the problems of branches has ever been a technological one. Feature branches means losing continuous integration. I don’t like them.