Feature Flags: A Potential Source of Evil and Zombie-Like Resurrections
TL;DR: Don't leave unused code lingering. Clean up your feature flag debris.
The Problems
- Dead Code
- Maintainability
- Unnecessary complexity
Proposed Solutions
- Clean out dead code
- Establish a clear lifecycle for your feature flags
Background
Feature flags are commonly used to toggle certain features or functionalities on or off dynamically, allowing for controlled rollouts or A/B testing.
However, if the code regulated by these flags becomes obsolete or is no longer necessary, it can result in dead code. Not only does dead code clutter the codebase, making it more challenging to understand and maintain, but it can also confuse developers, giving the false impression that certain functionalities are still active and supported when they aren't.
A notable example of this occurred with the Knight Capital Group. Old code, left active under a feature flag alongside new code, caused the system to send a massive volume of incorrect orders to the market, leading to losses of approximately $440 million for Knight Capital Group in a matter of minutes, nearly resulting in bankruptcy for the firm.
Sample Code
Incorrect Approach
public class WeatherSimulation {
private boolean isWeatherSimulationEnabled ;
// This feature flag controls weather simulation
public WeatherSimulation() {
Properties config = new Properties();
FileInputStream fis = new FileInputStream("config.properties")) {
config.load(fis);
isWeatherSimulationEnabled = Boolean.parseBoolean(
config.getProperty("weatherSimulation.enabled", "false"));
// The feature toggle is read from the file
isWeatherSimulationEnabled = false;
}
}
public void simulateWeather() {
if (isWeatherSimulationEnabled) {
// Code to simulate weather conditions
// ...
System.out.println("Simulating weather...");
}
}
}
Correct Approach
public class WeatherSimulation {
public WeatherSimulation() {
Properties config = new Properties();
FileInputStream fis = new FileInputStream("config.properties")) {
config.load(fis);
String weatherSimulationEnabledValue =
config.getProperty("weatherSimulation.enabled");
if (weatherSimulationEnabledValue != null) {
throw new IllegalStateException(
"weatherSimulation.enabled property " +
"should not be present in the configuration file.");
// Follow the fail-fast principle.
// The feature is deprecated
// and users have been notified during the grace period
// After this period, execution should be stopped
}
}
}
public void simulateWeather() {
// Remove the simulated code and simplify it
}
}
Detection
- [x]Semi-Automatic
Employ mutation testing and remove potential dead code to see if your coverage net identifies a defect.
Tags
- Bloaters
Level
- [x]Intermediate
AI Assistants
AI assistants usually don't add dead code or feature flags unless explicitly instructed to do so.
Conclusion
Regularly review and clean up feature flags and associated code to eliminate unnecessary or obsolete parts. This ensures that the code remains lean, comprehensible, and free from potential issues caused by dead code. Feature flags should have a short lifespan and their lifecycle must be supervised.
Relations
Code Smell 29 - Settings / Configs
Additional Information
Disclaimer - Code Smells reflect my opinion.
Credits - Photo by the blowup on Unsplash
"The software isn’t finished until the last user is dead."
Sidney Markowitz
This article is part of the CodeSmell Series.