Feature flags - twój przyjaciel czy wróg?

fsgeek.pl 2 lat temu

Jak wypuszczamy zmiany na proda, to muszą działać. A co jeżeli znajdziemy poważny błąd? Trzeba go gwałtownie naprawić albo cofnąć zmiany. Z Feature Flag możesz ukryć te zmiany w ciągu sekundy. Zobacz, czym są Feature Flags, jakie są zalety, wady i jak z nimi pracować.

Co to są Feature Flag?

Jest to technika, która umożliwia modyfikację systemu bez zmiany kodu. Sprowadza się to do umieszczenia w kodzie specjalnych zmiennych (flag), które są sterowane z innego miejsca, aplikacji. Ja to zacząłem określać ostatnio jako Ifs as a service.

if(fetaureFlagSerivce.someFlag){ return ... }else{ return ... }

Zalety Feature Flag

Zacznę od zalet, bo feature flag ma ich naprawdę sporo. I do wielu fajnych rzeczy da się je wykorzystać.

Wypuść na produkcję teraz, aktywuj później

Główna zaleta Feature Flag to możliwość mergowania nowych funkcjonalności do głównego brancha i aktywowanie, dopiero gdy są gotowe. Dzięki temu nie trzymasz zmian za długo na osobnym branchu i nie musisz się martwić mergowaniem i rozwiązywaniem konfliktów. Dodatkowo wszystkie zmiany są małe i wprowadzane stopniowo co ułatwia proces Code Review.

Guzik bezpieczeństwa

Jeśli nowa funkcjonalność nie działa, to można gwałtownie ją wyłączyć i spokojnie pracować nad poprawką. Nie musisz robić na gwałtownie hotfixa, wycofywać zmian itd.

Warunkowy dostęp

Korzystając z feature flags, możemy konfigurować dostęp do danej funkcjonalności np.: na bazie języka, kraju, dat itd. Jest to wygodne, gdy aplikacja jest dostępna w różnych krajach i dostępność opcji jest różna dla wszystkich.

Zdalna konfiguracja

Bardzo często feature flag to nie tylko flaga typu true/false, ale również inne wartości, które możesz wykorzystać do konfiguracji aplikacji. Dzięki temu możemy wprowadzać drobne zmiany w zachowaniu aplikacji. Jednak nie polecam tak robić, bo zwiększa to stopień skomplikowania kodu.

Canary deployments

Z feature flags możesz zdefiniować, ilu użytkowników ma widzieć nową funkcjonalność i jeżeli wszystko działa to stopniowo zwiększać do 100%. Na początek możesz zacząć z małą ilością klientów i sprawdzić, czy wszystko działa. Albo dać dostęp do early features i wypuszczać tylko dla tej grupy na początku.

Testy A/B

Podobnie jak w przypadku Canary Deployments można zdefiniować, ile procent użytkowników ma widzieć nową funkcjonalność i potem zdecydować, która wersja jest lepsza. Dzięki temu można na gwałtownie sprawdzić, czy dana zmiana wprowadzi zysk do aplikacji. Trzeba pamiętać o usuwaniu takich flag po eksperymencie (i nie prowadzić go wiecznie).

Wady Feature Flag

Jednak nie jest to idealne rozwiązanie. Wprowadzenie go do kodu wiąże się z problemami, które musimy zaakceptować.

Uzależniające

Korzystanie z flag jest bardzo uzależniające. Szczególnie dla klienta, który może włączać i wyłączać funkcjonalności bez pytania programisty o zdanie. Bardzo trzeba uważać na wprowadzanie flag, wszędzie gdzie się da. Klient nie wie, iż to komplikuje kod - my musimy mu to uświadomić.

Wprowadza dług do kodu

Wprowadzenie flagi do kodu, powoduje powstanie długu. I ten dług rośnie wraz z czasem, gdy zapominamy, od czego jest ta flaga. Wtedy usunięcie flagi jest mniej bezpieczne i niechętnie się do tego zabierzesz. Powoduje to lawinowe powstawanie kolejnych flag i zaśmiecanie kodu dużą ilością if'ów.

Nieoczekiwane zależności

Przy jednej fladze nie ma tego problemu. Gdy jest więcej flag, to może się okazać, iż przy niektórych kombinacjach flagi powodują błędy albo ślepe zaułki. Również dotarcie do jednej flagi może wymagać poprawnych wartości na kilku poprzednich. A to prowadzi do...

Trudności w debugowaniu

Dużo trudniej debuguje się błędy z produkcji, ponieważ trzeba znać wszystkie informacje o flagach, by móc odtworzyć błąd. I bardzo dobra znajomość ścieżek w aplikacji, by odtworzyć tą od użytkownika. jeżeli chcesz mieć flagi w aplikacji, najpierw zainwestuj w dobre logowanie błędów i informacje o użytkowniku.

Dobre praktyki dla feature flag

Dobrze nazywaj

Ta rada sprawdza się, w każdym aspekcie programowania. Przy flagach ma kolosalne znaczenia. Większość informacji o fladze jest w zewnętrznym systemie. I poruszając się po kodzie, musisz na podstawie samej nazwy określić, do czego służy ta flaga.

Opisuj co flaga robi

Jeżeli system w którym tworzysz flagi, pozwala ci na dodatkowy opis, to koniecznie go zrób. Po co jest ta flaga, gdzie będzie głównie wykorzystywana, czy ma być tymczasowa, czy na stałe itd. Wszystkie informacje, które tutaj umieścić uproszczą ci życie za miesiąc, pół roku czy rok, gdy będziesz musiał coś zmodyfikować lub usunąć.

A jeżeli system nie pozwala na opisy, to stwórz osobne miejsce do trzymania tych informacji.

Nie stosuj konwencji disable/hide

Miej litość dla siebie i innych i nie twórz flag negatywnych. O co mi chodzi? Zerknij na przykład:

if(someFlagDisabled && !someFlag2Disabled){ }

Czy jesteś w stanie powiedzieć co zrobić, żeby wejść do if'a? Czy musisz się jednak zastanowić? A co gdyby warunków było więcej?

A co gdybyśmy zmienili w ten sposób?

if(someFlagEnabled && !someFlag2Enabled){ }

Tu już dużo łatwiej podać warunki, by wejść do if'a.

Negatywne warunki są nielogiczne - musi być false, aby funkcjonalność była aktywowana. Niech twoje flagi będą logiczne i nie wymagały wysiłku, do określenia czy coś jest włączone, czy nie.

Regularnie rób audyt

Flagi mają to do siebie, iż łatwo o nich zapominamy. Szczególnie te, które były nam potrzebne przy wypuszczaniu nowej funkcjonalności. Po wypuszczeniu, jeżeli wszystko działa to mamy opuszczoną flagę, która zwiększa złożoność kodu. Dlatego raz na jakiś czas przejrzyj flagi i wyrzuć te, które już nie są używane. Podziękujesz sobie w przyszłości. Uwierz mi, usuwanie ponad rocznej flagi nie jest przyjemne.

Stwórz dokument z opisem flag i zależności między nimi

Jest to rozwinięcie opisu flagi. Gdy mamy w systemie dużo, różnych flag to zaczynają się pojawiać związki pomiędzy nimi. I nie są one oczywiste, jeżeli właśnie nad tym nie pracujesz. Chodzi mi o sytuacje gdy, żeby dotrzeć do jednej flagi, musisz mieć odpowiednie warunki w jednej lub więcej innych. I warto zapisywać te zależności, bo przydają się do:

  • debuggowania,
  • usuwania w przyszłości,
  • zarządzaniem dodawaniem kolejnych flag.

Mając taką dokumentację, możemy powiedzieć w pewnym momencie STOP, gdy logika robi się zbyt skomplikowana.

Idź do oryginalnego materiału