Today, I’m gonna tell you a story. A story about how to deploy unstable features without compromising the application.
While working on the projects, I’ve been asked to develop many features in an early stage. When the specifications were not finished, or the integration was partial.
How to rollout the complete application when only a single feature isn’t finished? I don’t want a single feature to block the rollout of a new version of my application.
How to solve this situation without spending two more weeks finishing the work?
Feature flags
What if I push the code, but with the feature disabled?
Let’s start assuming I want to use the feature flags at the beginning.
The easiest way is to create a constant which indicates the feature is disabled. Then, surround my new feature with if conditions.
public class MyService {
private static final boolean FEATURE_FLAG = false;
public void handleRequest() {
if (FEATURE_FLAG) {
handleNewVersion();
} else {
handleOldVersion();
}
}
}
That’s clean. But usually, I know a feature is unstable and I want to hide it at the last minute.
Ok, no problem. Git is my friend.
Let’s pick all the classes with changes and rename them. Let’s restore the original files from Git. Now, use one class or the other depending on the feature flag.
public class MyController {
private static final boolean FEATURE_FLAG = false;
private final MyNewService myNewService;
private final MyOldService myOldService;
@PostMapping("/do")
public ResponseEntity<Void> doSomething() {
if (FEATURE_FLAG) {
myNewService.handleRequest();
} else {
myOldService.handleRequest();
}
}
}
Dynamic feature flag
All this sounds good when I really don’t want to execute the code. I’ll need to rollout my application again to enable the feature.
But want if I want to test the feature? Enable it for some days, disable it, and compare both behaviors.
Ok, that’s more like A/B testing.
For those situations, I have a table in the database called FeaturesConfiguration. I store there all the features flags. So, instead of reading my feature flag values from contants, I read them from the database.
And when I want to change the behavior, I update the value in the database.
Warnings
This seems to be the solution for all the stable features. But there are some considerations to take into account.
This generates two workflows. With the feature enabled and with the feature disabled. I have to test my application in both workflows. Ensure the application is stable in both situations. Otherwise, I can’t use the dynamic feature flags. I must wait until the feature is stable.
Clean up
Once the feature is fully developed and deployed, I don’t need the flag anymore.
It will be activated all the time.
Here is when I must clean up my code to remove all the conditions. Otherwise, I need to maintain two versions of the application. That’s a lot of work.
Conclusion
When do I use feature flags? With features which need a long time to be developed. When I want to split the deployment of a feature.
Or when a feature seems to be unstable at the end of the release cycle, and we try to fix again and again the bugs. When you mix the rush with an unstable feature, you never have a good result.



Leave a comment