1
 
 
Account
In your account you can view the status of your application, save incomplete applications and view current news and events
September 09, 2013

Continuous Delivery with Feature Toggles

What is the article about?

In many projects, the development of new features is done in one or another branching model, such as Git Flow: Features are first developed on a separate branch and only integrated again after the feature is "finished". When merging the changes, there are sometimes conflicts and if you are unlucky, you end up in "merging hell".

Modern VCSs such as GIT make branching and merging much easier, but they do not change the fact that it is occasionally difficult to integrate competing changes into a runnable deployment. The main problem with feature branches, however, is a different one: When is a feature "ready", i.e. can it be integrated? If a story is accepted on the basis of the feature branch, further quality assurance must take place after integration - otherwise errors could creep in when combined with features developed in parallel. If quality assurance only takes place after integration on a release branch, it could turn out that the feature is not ready after all because one or the other requirement has not been met. Continuous Integration therefore follows a different path: development takes place on the HEAD and each commit is integrated directly in an automated manner. Jenkins, TeamCity or other tools help to regularly create an up-to-date build every few minutes and deploy it to a CI server.

The acceptance of the features takes place either on the CI server or a separate stage of the build pipeline.

Very good automated test coverage is a prerequisite for ensuring that the software is executable at all times and that all requirements remain met. Feature toggles ensure that a feature is not activated until it has been completed and approved by quality assurance. For this purpose, the new features of the software are toggled using simple if statements:

if (Features.NEW_FANCY_FEATURE.isActive()) {
useMyFancyNewFeature();
} else {
doTheOldBoringStuff()
}OldBoringStuff() }

Using feature toggles gives us a whole new set of options for making features live. Namely, features can also be activated gradually via "valves" (Valves, Activation Strategies):

  • Initially only for individual users, for example testers, product owners or "friendly customers".
  • For one percent of the users, later 50% with an A/B test that ensures the success of the feature, then at some point for all users.
  • Time-controlled, e.g. in order to switch on a release date.
  • Features can also be activated on only one server of the cluster.
  • ...and of course environment specific for one or more stages of the deployment pipeline.

So the final decision whether a new feature goes online can be done in the live environment, which helps to deploy regularly and short timed. In the "Discover" team, we have been using Feature Toggles for some time now. Currently, we go live in our team alone(the system consists of several loosely coupled applications) several times a week, sometimes several times a day. Integrating Feature Toggles into the software is easy. A rudimentary solution is quickly developed in-house, but there are also ready-made solutions. Some time ago we switched from a self-developed solution to the Togglz Library: a fancy, lean library that can be integrated very easily into all kinds of Java applications and also comes with a console to manage the toggles. The above mentioned"Activation Strategies" are supported (among others), a rights management can be easily integrated and the persistence of toggle settings is also easily possible.

screenshot-admin-console.
screenshot-admin-console.

Togglz Administration Console toggles are used in various situations:

Togglz Administration Console toggles are used in various situations:

  • Newly developed features are initially disabled. In tests and test environments new features are switched active.
  • All caches are switched via (by default activated) toggles. If there are inconsistencies in the cached data, caching can be disabled.
  • Certain functions are permanently protected by toggles: for example, we can disable access to non-critical external systems or switch off all personalization so that only cacheable pages are delivered.

The Togglz Library supports such groupings via the FeatureGroup annotation. We have written our own annotations for the various use cases. Features that are still under development are switched via the InDevelopment, for example:

@FeatureGroup
@Label("Features in development")
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface InDevelopment {
}
public enum Features implements Feature {
@Label("Only load product recommendations asynchronously using AJAX")
@InDevelopment
USE_AJAX_FOR_PRODUCT_RECOMMENDATIONS,
...

In the Togglz Console, the FeatureGroups are displayed as tabs in which the features belonging to the group are automatically sorted.We had to get used to the development with Feature Toggles: If too few toggles are used, existing features can be affected by page effects. But if we overdo it, the readability and testability of the code suffers. Above all, however, it is important to remove toggles that are no longer needed from the code.The advantages far outweigh these initial difficulties, however. In addition to the new possibilities for live development, the toggles allow us to continuously integrate and frequently move into production. Feedback cycles become very short this way and we can push frequent small commits directly on the HEAD, avoiding costly merges: One new test, one small change, one commit. In combination with BDD, TDD, build pipelines, non-disruptive deployments and a rollback-capable application, we are on the best way towards Continuous Delivery with Feature Toggles.

2Comments

  • José Stiller
    02.10.2013 15:54 Clock

    Ich hätte noch ein paar Fragen zum Verständnis sofern das erlaubt ist. Falls nicht bzw. wenn ich einfach falsch liege oder eine falsche Annahme mache, bitte gerne korrigieren!

    Am Anfang beschreibst du ein Problem bezüglich der Qualitätssicherung nach der Fertigstellung eines Features. Den Merging Hell lass ich mal außen vor. Ist halt so. Du stellst die Frage wann etwas getestet werden muss. Meiner Meinung nach, wird doch in dem jeweiligem Branch nach Fertigstellung des Features oder idealerweise täglich ein Rebase mit dem Master sowie nach der Fertigstellung des Features ein Rebase mit dem Master durchgeführt. Und da es sich beim Master immer um eine lauffähige Version handelt, könnte man dann doch problemlos auch im Branch testen. Was nun passieren könnte, wäre dass während des Testens sich der Master nochmal verändert hat. Aber wenn man diese Annahme zugrunde legt, müsste man Prinzipiell nach der Fertigstellung eines Features immer alles Testen, da es dann quasi immer Seiteneffekte haben könnte. Daher wahrscheinlich der Schritt Richtung CI um automatisiert testen zu können. Ich nehme mal an, dass die Software ohnehin schon lose gekoppelt war um es generell leicht testen zu können.

    Weiterhin hätte man die Feature Toggles auch unabhängig von allem dem einführen können oder? Denn dann würde ich den Artikel so verstehen, dass man gerne im Sinne von TDD über BDD mit Hilfe von Continuous Integration hin zum Continuous Delivery kommen möchte um unterbrechungsfrei deployen zu können. Und das dabei die Feature Toggles sehr Hilfreich sind und damit eine Neuerung! Oder habe ich das falsch verstanden.

  • Guido Steinacker
    05.10.2013 13:21 Clock

    Hallo José,

    natürlich findet man auch mit einem Branching-Modell einen Weg, Features zu testen, keine Frage. Branches führen aber tendenziell zu etwas längeren Release-Zyklen, als wenn man den CI-Ansatz verfolgt, in dem zumindest theoretisch jeder Commit Livegestellt werden kann. CI und Feature-Branches vertragen sich nicht sonderlich gut miteinander: Wenn man mit Feature-Branches arbeitet, werden die Features auf dem Branch "fertig"gestellt, bevor integriert wird. Die Integration wird dadurch sehr viel grob-granularer, als wenn kontinuierlich integriert wird.
    CI führt zwangsläufig zu einer sehr hohen automatisierten Testabdeckung. Feature-Branches sind in dieser Hinsicht etwas weniger anspruchsvoll. Branches führen eher zu "Releases", während CI in Richtung Continuous Delivery führt.
    Vor der Livestellung eines Features sorgfältig zu testen ist in beiden Modellen erforderlich. Bei Feature-Branches erfolgt dieser Test aber nach Fertigstellung, während Feature-Toggles zumindest prinzipiell die Livestellung "unfertiger" Features ermöglichen. Die Integration der einzelnen Commits erfolgt bei Branches also deutlich später, was zu größeren Änderungen in den Deployments führt, die dann aufwändiger zu testen sind (viele Änderungen erhöhen das Risiko, dass sich viele Fehler eingeschlichen haben).
    Toggles lassen sich auch in der Entwicklung mit Feature-Branches einsetzen: beispielsweise um Features "im Notfall" zu deaktivieren, für A/B-Tests oder um ein Feature nach und nach auszurollen. Ganz bestimmt kann man auch Wege finden, Branches und Toggles zu kombinieren. Es sind halt Werkzeuge, die man bewusst einsetzen muss.

    Viele Grüße, Guido

Write a comment
Answer to: Reply directly to the topic

Written by

Guido Steinacker
Guido Steinacker
Executive Software Architect

Similar Articles

We want to improve out content with your feedback.

How interesting is this blogpost?

We have received your feedback.

Cookies erlauben?

OTTO und drei Partner brauchen deine Einwilligung (Klick auf "OK") bei einzelnen Datennutzungen, um Informationen auf einem Gerät zu speichern und/oder abzurufen (IP-Adresse, Nutzer-ID, Browser-Informationen).
Die Datennutzung erfolgt für personalisierte Anzeigen und Inhalte, Anzeigen- und Inhaltsmessungen sowie um Erkenntnisse über Zielgruppen und Produktentwicklungen zu gewinnen. Mehr Infos zur Einwilligung gibt’s jederzeit hier. Mit Klick auf den Link "Cookies ablehnen" kannst du deine Einwilligung jederzeit ablehnen.

Datennutzungen

OTTO arbeitet mit Partnern zusammen, die von deinem Endgerät abgerufene Daten (Trackingdaten) auch zu eigenen Zwecken (z.B. Profilbildungen) / zu Zwecken Dritter verarbeiten. Vor diesem Hintergrund erfordert nicht nur die Erhebung der Trackingdaten, sondern auch deren Weiterverarbeitung durch diese Anbieter einer Einwilligung. Die Trackingdaten werden erst dann erhoben, wenn du auf den in dem Banner auf otto.de wiedergebenden Button „OK” klickst. Bei den Partnern handelt es sich um die folgenden Unternehmen:
Google Inc., Meta Platforms Ireland Limited, elbwalker GmbH
Weitere Informationen zu den Datenverarbeitungen durch diese Partner findest du in der Datenschutzerklärung auf otto.de/jobs. Die Informationen sind außerdem über einen Link in dem Banner abrufbar.