A Double Edged Sword - Feature Toggles and Trunk-Based Development

A Double Edged Sword - Feature Toggles and Trunk-Based Development

Sunny Sun Lv4

Balancing Benefits and Risks

** This post is updated on 25-July-2024

My time working at ThoughtWorks(https://www.thoughtworks.com/en-au ), a leader in Agile development, instilled in me the value of “sensible defaults” (https://www.thoughtworks.com/en-au/insights/blog/digital-transformation/Digital-talent-defaults-for-agile-org ). These are best practices designed to streamline software delivery. Two impactful practices are Feature Toggles and Trunk-Based Development (TBD). These approaches form the backbone of ThoughtWorks’ methodology due to their ability to optimize development and facilitate rapid iteration.

While Trunk-Based Development can spark debate, even within ThoughtWorks. Its benefits are undeniable when applied to the right project with proper implementation. This blog delves deeper into Feature Toggles and TBD, exploring their advantages, when they should or should not be used, and potential limitations.

Jump ahead:

How feature toggle works?

Feature Toggles (often also refered to as Feature Flags) is a technique, allowing teams to modify system behavior without changing code.

At their core, feature toggles are conditional statements within our code that determine whether a feature should be enabled or disabled. This decision is often based on configuration settings, user roles, or other criteria. By strategically placing these toggles throughout our application, we gain granular control over feature exposure.

Feature toggle allows developers to safely “toggle” new features on or off for testing. Feature toggles have many use cases beyond testing, such as the targeted rollout or quick rollback of new features in production, experimentation, canary releases, operations, or activation of premium features.

Key Benefits of Feature Toggles

Feature Toggles complement Trunk-Based Development by safely integrating incomplete features into the main branch. This way, the main branch is always in a deployable state, and teams can work on features without long-lived branches.
Some of the key benefits are:

  • Gradual Rollouts: Introduce new features to a subset of users to gather feedback and monitor performance before a full-scale release.
  • A/B Testing: Experiment with different feature variations to determine the most effective approach.
  • Kill Switches: Quickly disable problematic features to minimize impact on users.
  • Feature Flipping: Enable or disable features based on specific conditions, such as user segments or environmental factors.

Next, let’s explore how a feature toggle is applied with an simple example.

Example

Imagine a simple .NET Core application. We want to introduce a new feature with feature toggle.

Setting up the Feature Toggle

First, we define a feature toggle service. For simplicity, we can use a configuration-based approach.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// IFeatureToggleService.cs  
public interface IFeatureToggleService
{
bool IsFeatureEnabled(string feature);
}

// FeatureToggleService.cs
public class FeatureToggleService : IFeatureToggleService
{
private readonly IConfiguration _configuration; public FeatureToggleService(IConfiguration configuration)
{
_configuration = configuration;
} public bool IsFeatureEnabled(string feature)
{
return _configuration.GetValue<bool>($"Features:{feature}");
}
}

Configure and use the Feature Toggle

In appsettings.json, we add our feature flags.

1
2
3
4
5
{  
"Features": {
"NewFeature": true
}
}

Here, we store the feature toggle setting in the config file for simplicity. In real-world projects, it is recommended that the settings be stored in a database. By storing the feature toggle settings in the database, you can change the state of a feature (on/off) and see those changes reflected instantly within your application.

This is particularly important because it allows product owners and stakeholders to have instant control over the visibility of new features, enabling them to be showcased and explored in isolation before being released to production users.

To use the feature toggle service is as simple as injecting the feature toggle service and an if statement, as in the example below.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
 public HomeController(IFeatureToggleService featureToggleService)  
{
_featureToggleService = featureToggleService;
} public IActionResult Index()
{
if (_featureToggleService.IsFeatureEnabled("NewFeature"))
{
ViewBag.Message = "New Feature is Enabled!";
}
else
{
ViewBag.Message = "Welcome to our website!";
} return View();
}
}

When Not to Use Feature Toggles

While feature toggles offer flexibility, they shouldn’t be a permanent solution. Here’s when to consider alternatives:

  • Core Functionality: Don’t toggle essential features that define your application’s core behavior.
  • Complex Logic: Avoid intricate logic based on toggles, which can lead to maintenance headaches.
  • Short-Lived Features: If a feature is very short-lived or experimental, the overhead of adding and managing a toggle might not be worth it.

Trunk-Based Development: a close look

What is trunked-based development

Trunk-based development (TBD) is a version-control branching model in which developers integrate small, frequent changes into the main branch (trunk). With trunk-based development, your team integrates changes directly into the main branch (trunk), whereas other branching strategies like GitFlow involve integrating into multiple feature branches.

TBD doesn’t mean we completely ditch feature branches. Instead, these branches are kept short-lived. We can still use them for code review, merge requests, and branch builds to get quick feedback. The key difference is that you avoid long-lived branches like release branches.

While TBD might seem counterintuitive at first, it offers several advantages:

  • Faster deployment: By eliminating the complexities of merging long-lived branches, teams can deploy more frequently.
  • Improved code quality: Constant integration forces developers to address merge conflicts promptly, leading to a cleaner codebase.
  • Reduced risk: Smaller, frequent commits mitigate the risk of large, untested changes.

Prerequisite for TBD

Trunk-based development can be a very efficient and powerful tool only if the team meets the conditions below:

  • A capable team with a high level of trust between the members. TBD often works well with a small and skillful team. It is key to have a strong dev team. Without it, the TBD will cause more harm than good.
  • Automated unit and integration testing in place with good test coverage.
  • A solid CI pipeline

Implementing trunk-based development without those is a recipe for disaster. The common symptoms include frequent broken builds and code churn.

Some can argue that the benefits of Trunk-Based Development (TBD) are more a result of its prerequisites, like good unit test coverage, rather than TBD itself. This argument is not wrong. However, TBD acts as a framework that enforces practices like good test coverage, continuous integration, early feedback, and clear communication. These practices, in turn, create an environment where good unit test coverage flourishes and delivers its benefits.

TBD only works with a strong team

The success of trunk-based development hinges on a strong, well-coordinated team. Without a culture of clear communication, mutual respect, and a willingness to learn from each other, especially for less experienced developers, the challenges of trunk-based development can quickly become overwhelming.

The clear communication between teams is essential. The team members must talk openly to fix problems quickly and share any changes affecting the main codebase (trunk).

Another good practice that complements TBD is pair programming. As developers work together, code reviews become part of the development process. This allows for immediate feedback, early bug detection, and knowledge sharing. However, to avoid burnout, pair programming should be an opt-in approach. Developers should choose when collaboration can be most beneficial.

TBD and feature toogle

TBD and feature toggles are complementary practices used in Agile development. We can use feature toggles in development without adapting TBD, but they are often combined together.

Trunk-Based Development emphasizes frequent integration of code changes into the main branch, minimizing the complexity of merge conflictsc. However, it can introduce challenges in managing incomplete features.

Feature Toggles address this by allowing developers to integrate code into the main branch while keeping features hidden until they are ready for release. This approach preserves the benefits of TBD while mitigating the risk of unstable code impacting production.

By combining TBD and feature toggles, teams can achieve a high degree of agility and control over their software development process. Feature toggles enable safe experimentation and gradual feature rollouts within the context of a trunk-based workflow.

Summary

Feature toggles and trunk-based development are powerful tools for modern software development teams. By combining these practices, teams can significantly enhance their ability to deliver software faster, more reliably, and with greater control.

Feature toggles allow developers to experiment with new features without disrupting the main codebase, while trunk-based development promotes continuous integration and reduces the complexity of managing multiple branches. Together, they form a potent combination for achieving rapid and iterative development.

It’s crucial to remember that feature toggles are a temporary mechanism and should be removed once a feature is fully released or abandoned. Overreliance on feature toggles can lead to code clutter and maintainability issues.

  • Title: A Double Edged Sword - Feature Toggles and Trunk-Based Development
  • Author: Sunny Sun
  • Created at : 2024-06-21 00:00:00
  • Updated at : 2024-07-27 15:06:00
  • Link: http://coffeethinkcode.com/2024/06/21/a-double-edged-sword-feature-toggles-and-trunked-based-development/
  • License: This work is licensed under CC BY-NC-SA 4.0.