Code Smell 242 - Zombie Feature Flags

Written by mcsee | Published 2024/02/22
Tech Story Tags: clean-code | code-smells | code-refactoring | unused-code | zombie-feature-flags | feature-flags | software-complexity | code-maintainability

TLDR Feature flags, while useful for controlled rollouts and experimentation, can become problematic if not managed properly, leading to dead code and increased complexity. Learn how to mitigate these risks by implementing clear lifecycle management for feature flags and conducting regular code cleanup to maintain a lean and reliable codebase.via the TL;DR App

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

  1. Clean out dead code
  2. 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 09 - Dead Code

Code Smell 29 - Settings / Configs

Additional Information

https://dougseven.com/2014/04/17/knightmare-a-devops-cautionary-tale/?embedable=true

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

https://hackernoon.com/400-thought-provoking-software-engineering-quotes?embedable=true

This article is part of the CodeSmell Series.

https://hackernoon.com/how-to-find-the-stinky-parts-of-your-code-part-i-xqz3evd?embedable=true


Written by mcsee | I’m senior software engineer specialized in declarative designs and S.O.L.I.D. and Agile lover.
Published by HackerNoon on 2024/02/22