Przejdź do treści

Wprowadzanie skomplikowanych zmian z użyciem Feature Flag

Są zadania, których się nie da zrealizować w jeden dzień.

Wyobraźmy sobie, że musimy dostarczyć nowszą wersję już istniejącej integracji w naszym systemie. Api po drugiej stronie jest zupełnie inne. Środowisko testowe naszego partnera nie istnieje lub nie działa. Naszym zadaniem jest dostarczyć nową wersję integracji i przełączyć wszystkich naszych użytkowników na nową implementację.

Może się pojawić pokusa, aby stworzyć nowy branch, rozpocząć pracę nad dostosowaniem integracji w tym branch'u i kontynuować ją przez najbliższe pół roku. Jak już wspomnieliśmy, niesie to za sobą wiele ryzyk, nie mówiąc o tym, że w międzyczasie logika biznesowa naszej integracji może ulec zmianie, co oznacza rozwiązywanie konfliktów.

Branch By Abstraction

Zastosowanie Feature Flag pozwala nam na zastosowanie techniki Branch By Abstraction.

Algorytm postępowania

  1. Zidentyfikuj miejsca w kodzie, gdzie uruchamiany jest kod, który wymaga wymiany.
  2. Stwórz dodatkową warstwę w swoim kodzie, której zadaniem będzie tylko i wyłącznie przekazywać wywołania do starego kodu. We wszystkich zidentyfikowanych miejscach wprowadź modyfikację by, zamiast wywoływać bezpośrednio stary kod, wywoływać nową warstwę abstrakcji. Dla użytkownika na tym etapie nie powinno być żadnych widocznych zmian funkcjonalnych. Dla testów integracyjnych takie rozwiązanie powinno być przezroczyste.
  3. Po upewnieniu się, że nasza zmiana nie zepsuła aplikacji, wyślij kod do współdzielonego repozytorium.
  4. Stwórz drugą implementację dla naszej warstwy abstrakcji, wybór implementacji, która ma zostać uruchomiona, uzależnij od stanu Feature Flag'i. Przetestuj i wyślij zmiany.
  5. Kontynuuj pracę nad nową implementacją, wysyłając stabilne zmiany do współdzielonego repozytorium. W tym czasie wszelkie zmiany w logice biznesowej starej implementacji nadal są możliwe i nie prowadzą do konfliktów.
  6. Gdy implementacja jest gotowa, zmigruj wymagane dane, przełącz flagę.
  7. Usuń starą implementację.
  8. Usuń dodatkową warstwę abstrakcji i Feature Flag'ę.

Przykład z wymianą integracji

  1. Zidentyfikuj wszystkie miejsca w kodzie, gdzie uruchamiany jest kod integracji, którą chcemy wymienić.
  2. Stwórz klasę, która niczym warstwa abstrakcji (taki pośrednik) będzie implementowała metody, których wymaga nasza aplikacja, a implementacja tych metod, to po prostu bezpośrednie wywołania metod starej integracji.
  3. Dostarcz drugą implementację metod w warstwie abstrakcji, zgodną z nową wersją integracji. Uzależnij wybór implementacji metod w warstwie abstrakcji od Feature Flagi.
  4. Przełącz flagę.
  5. Usuń starą implementację integracji.
  6. Usuń warstwę abstrakcji i Feature Flag'ę, wywołując metody nowej integracji bezpośrednio w kodzie naszej aplikacji.

To nie jest rozwiązanie wszystkich problemów

Jeśli musimy utrzymywać kilka wersji naszego API lub przewidujemy, że migracja na nową implementację potrwa długo, to może lepiej pomyśleć o mniej tymczasowym rozwiązaniu.

Poziom skomplikowania

Ktoś mógłby powiedzieć, że zastosowanie tej techniki wymaga napisania większej ilości kodu, jest trudniejsze i przez to prace potrwają dłużej. Owszem, stosowanie Branch By Abstraction wymaga pewnych umiejętności programistycznych, jednak stwierdzenie, że prace potrwają dłużej, nie jest uzasadnione.

Jeśli prace w modelu gitflow, na osobnym branch'u, są szacowane bez uwzględnienia ryzyka dodatkowych prac związanych z rozwiązywaniem konfliktów, ciągłym utrzymaniem logiki biznesowej w 2 branch'ach i nieprzewidywalnej ilości zmian po wielkim code-review na koniec, to faktycznie, ciężko będzie z takim oszacowaniem konkurować.

Zastosowanie Branch By Abstraction pozwala nam podzielić prace na małe, wdrażalne (aczkolwiek schowane za Feature Flag'ą) kawałki i pozostanie przy pracy w gałęzi głównej (trunk). Znanej i szacowalnej pracy jest więcej. Praktycznie nic nie jest w stanie nas zaskoczyć. Ryzyko, że termin dostarczenia całego rozwiązania się wydłuży, jest dużo mniejsze.

Dla tych, którzy nie czują się przekonani: Porozmawiajcie szczerze z biznesem. Spytajcie, która opcja jest dla nich lepsza.

Biznes zna konsekwencje niedotrzymanego terminu, który został obiecany klientowi i jestem przekonany, że potrafi zarządzać ryzykiem opóźnień.

Więcej informacji

Technika Branch By Abstraction została szczegółowo opisana na stronie https://www.branchbyabstraction.com