Przejdź do treści

Feature Flagi - co to takiego?

Stosowanie Feature Flag jest sposobem na kontrolowanie zachowania aplikacji, bez konieczności wprowadzania zmian w kodzie logiki biznesowej.

O Feature Fladze można pomyśleć jak o przełączniku (Feature Toggle). Podstawowy koncept zakłada, że flagę można włączyć (ustawić jej wartość 1 lub true) lub wyłączyć (ustawić jej wartość 0 lub false).

Feature Toggle

W Internecie można spotkać określenie Feature Toggle. To alternatywne określenie na ten sam koncept. Pojęcie Feature Flag jest jednak częściej używane w branży.

Załóżmy, że podczas uruchomienia aplikacji jesteśmy w stanie ustawić stan wybranej przez nas flagi. Np. uruchamiając aplikację z CLI, możemy parametrem kontrolować stan flagi:

chrome --enable-auto-reload

Takie polecenie uruchomi przeglądarkę i dodatkowo aktywuje kod odpowiedzialny za automatyczne odświeżanie strony, jeśli podczas próby jej wyświetlenia dojdzie do błędu.

Aplikacja zazwyczaj ma jakieś miejsce, w którym przechowuje domyślny stan flag. Ten stan może być ustalany w procesie budowania lub przy instalacji aplikacji, lub przy uruchomieniu. Czasami domyślny stan flag jest po prostu umieszczony w kodzie aplikacji, w formie tablicy asocjacyjnej lub hashmap'y.

Wyobraźmy sobie prosty przykład, w którym uzależnimy wykonanie naszego kodu od stanu flagi show_hello_world.

<?php 
if($featureFlags['show_hello_world']){
    echo "hello world";
}
if(featureFlags.get("show_hello_world")){
  System.out.print("hello world");  
}

Jeśli chwilowo pominiemy kwestię tego, jak ustalono wartości flag, to ich zastosowanie sprowadza się do prostego if'a w kodzie. Możemy sprawdzić, czy flaga jest włączona i wykonać określone operacje.

Możemy też sprawdzić, czy flaga jest wyłączona i wtedy wykonać jakąś operację, ale jeśli to możliwe, to bardziej intuicyjne będzie odpowiednie nazwanie flagi, dodając w jej nazwie swego rodzaju zaprzeczenie, np. hide_something lub disable_something.

Jak stosowanie Feature Flag pomaga w Trunk Based Development?

Załóżmy, że rozpoczynamy pracę nad nową, rozbudowaną funkcją naszego systemu. Zaczynamy pracę nad nowymi klasami, implementujemy endpointy, dodajemy nowe pozycje do nawigacji w naszej aplikacji. Gdybyśmy stosowali gitflow, wszystko rozwijalibyśmy w osobnym branch'u i zrobili pull request dopiero wtedy, kiedy wszystko byłoby gotowe. Code review obejmowałoby wszystkie nowe klasy, kontrolery endpoint'ów, konfiguracje routing'u, modele biznesowe itd. W skrócie cały feature. Dużo.

W ramach Trunk Based Development moglibyśmy rozpocząć pracę podobnie, dodając Feature Flagę wszędzie tam, gdzie użytkownik lub system mógłby uruchomić nasz kawał kodu.

  • Flaga w konfiguracji routera, by endpoint nie działał.
  • Flaga w zadaniu cron, żeby nie wykonało logiki biznesowej.
  • Flaga w kontrolerze MVC, by użytkownik nie uruchomił żadnej akcji powiązanej z naszym kodem.
  • Flaga w konfiguracji nawigacji, by nie pokazać naszej nowej funkcji nikomu.

W ten sposób, o ile domyślnie Feature Flaga będzie wyłączona i dostarczymy składniowo poprawny kod, możemy taki kod wysyłać na produkcję. Jest tylko jedna zasada: zmiany nie mogą zepsuć aktualnie działającej aplikacji.

Skoro nikt i nic nie jest w stanie uruchomić tego fragmentu kodu, bo jest on schowany za if'em, który na produkcji się nie wykona, to nic nie stoi na przeszkodzie, żeby taki merge'ować i wdrożyć.

Dzięki temu można całą pracę podzielić na małe zadania i recenzować osobno. Konflikty, o ile w ogóle wystąpią, będą proste do rozwiązania.

Przy użyciu odpowiednich technik, takich jak Branch By Abstraction można też bezpiecznie modyfikować istniejące już funkcje systemu. Stosowanie Feature Flag pozwala też na bezpieczną migrację danych, bez konieczności wyłączania aplikacji, a nawet pozwala chronić nasz system przed skutkami awarii lub problemami wydajnościowymi.

Rodzaje flag

Rozwijając oprogramowanie, możemy dojść do wniosku, że nie każda flaga zastosowana w naszym systemie służy tylko i wyłącznie do celów deweloperskich, zamykając przed użytkownikiem możliwość uruchomienia niekompletnego rozwiązania.

Feature Flagi mogą mieć też szersze zastosowanie.

Flaga deweloperska

Ten rodzaj flagi omówiony został w ramach odpowiedzi na pytanie Jak stosowanie Feature Flag pomaga w Trunk Based Development?. Rozpoczynamy pracę nad nową funkcją naszego systemu, chcemy unikać konfliktów podczas merge'owania pracy, nie chcemy, aby użytkownik naszego systemu uruchomił taki kod.

Po zakończeniu prac taką flagę przełączamy dla części naszych użytkowników, w duchu canary deployment, aż do wdrożenia u wszystkich użytkowników. Po pewnym okresie przejściowym możemy usunąć taką flagę z naszego kodu.

Flaga migracyjna

Ten rodzaj flagi stosowany jest wtedy, kiedy chcemy zmodyfikować część naszego systemu na tyle istotnie, że zmienia się sposób przechowywania i dostępu do danych. Temat migrowania danych z użyciem Feature Flag został opisany osobno.

Flaga operacyjna

Flagi operacyjne pozwalają nam tymczasowo wyłączyć części systemu lub zredukować ich funkcje. Stosuje się je w sytuacjach awaryjnych, gdy część systemu przestaje działać prawidłowo i tym samym wpływa negatywnie na cały system.

Przykład zastosowania znajdziesz w części poświęconej sytuacjom awaryjnym.

Flaga biznesowa

Stosowanie w systemie flag deweloperskich i operacyjnych w pewnym momencie udowadnia jak elastyczne i sprawne jest to rozwiązanie. W tym miejscu tylko krok dzieli nas od sytuacji, w której ktoś spyta: czy możemy pewien feature włączyć tylko jednej grupie naszych klientów, którzy płacą więcej?

Odpowiedź brzmi: tak. Rozwiązanie technologiczne już istnieje, wystarczy z niego skorzystać, uzależniając stan flag od konkretnego użytkownika / wykupionego pakietu / kraju, w którym żyje użytkownik, czy innej segmentacji, która pasuje do naszego biznesu.