What are 'Feature Flags' and how to use them? (film, 53 minutes, PL)
Aleksander Paczek, a senior frontend developer at The Software House, presented the concept of feature flags in application design during his latest video. Feature flags, also known as toggles, allow developers to activate or deactivate functionalities in the application on the fly without deploying it. These flags provide teams with flexibility in updating and testing applications, enabling them to easily revert back to previous settings if problems arise. However, Aleksander emphasized that utilizing feature flags comes with certain issues and traps that one should be aware of before implementing them.
Aleksander discussed the advantages of using feature flags, highlighting that they allow for safe implementation of functionalities and mitigate risks associated with synchronization of code. Teams can introduce changes to the main code branch rather than maintain long-lived feature branches, which can lead to conflicts. Additionally, with the help of flags, teams can conduct A/B testing and implement canary deployment strategies, enhancing the likelihood of successful changes.
Yet, as Aleksander pointed out, feature flags are not without downsides. Their usage may lead to teams becoming addicted to their functionality, as well as increase code complexity and testing difficulties. The monumental number of flags can make the code harder to maintain, and the numerous combinations of conditions can lead to unforeseen bugs. Aleksander stressed that naming the flags, managing them, and proper documentation are key to effectively utilizing this technology.
A case example shared by Aleksander regarding a 'Black Friday' situation illustrates how feature flags can be beneficial in crisis situations. When problems arise in production, the team can quickly disable new functionalities and revert to the stable version of the application. The mentioned approaches, such as trunk-based development, minimize the need for synchronization and make deployments smoother and less burdened when it comes to releasing production versions.
Lastly, Aleksander drew attention to practicing good feature flag management strategies, suggesting that regular audits and adequate documentation of flags are essential for their effective use. He encouraged reflection on each new flag implementation to avoid unnecessary complications in the code, which over time can lead to the phenomenon of 'ifology'. At the time of writing this article, Aleksander's video amassed 879 views and 20 likes, which highlights his engagement and the understanding of the topic among viewers.
Toggle timeline summary
-
Introduction and hope to be heard.
-
Less coding discussion today, focusing on architectural concepts.
-
Explaining application design and improving it.
-
Discussion on feature flags in software development.
-
Personal experience with feature flags in projects.
-
Awareness of potential issues when using feature flags.
-
Presenter's introduction; Aleksander Paczek from The Software House.
-
Overview of today's presentation agenda.
-
Definition and explanation of feature flags.
-
Significance of changing application behavior without deployment.
-
Understanding feature flags as decision blocks in code.
-
Feature flags functioning similar to conditional statements.
-
Main functionality: release now, activate later.
-
Challenges of merging development branches.
-
Introduction of trunk-based development as an alternative.
-
Importance of testing prior to merging feature branches.
-
Advantage of making small changes frequently.
-
Feature flags as a solution for safe deployments.
-
Discussion on problems caused by feature flags.
-
Best practices to minimize challenges related to feature flags.
-
Regular audits of feature flags to manage technical debt.
-
Advice on the cautious introduction of feature flags.
-
Final thoughts on the importance of managing feature flags effectively.
-
Question and answer session begins.
-
Discussion of external tools for managing feature flags.
-
Summary of when to remove feature flags.
Transcription
Mam nadzieję, że mnie słychać. Dobra, więc tak, ja dzisiaj teraz troszeczkę będzie mniej kodu. Pozwolę sobie raczej podejść od strony troszeczkę bardziej takiej architektonicznej, czyli jak projektujemy aplikację, jak troszeczkę zrobić to lepiej. I chcę troszeczkę opowiedzieć o takim koncepcie jakim są feature flagi. Ja korzystam z nich w projekcie już od dłuższego czasu. I one ułatwiają wiele rzeczy, natomiast też trzeba wiedzieć o jakichś problemach, które bardzo często się będą pojawiały przy korzystaniu z nich. Dobra, więc tak, ja się nazywam Aleksander Paczek w firmie The Software House. Jestem senior frontend developerem, natomiast podobnie jak Wiktor zajmuję się też innymi rzeczami, bardzo często aplikacjami mobilnymi, ale również jakimiś tematami backendowymi, troszeczkę właśnie z projektowania aplikacji. No i w wolnym czasie dzielę się swoją wiedzą na blogu i też w newsletterze. Natomiast co dzisiaj? Po pierwsze, czym są feature flagi, ponieważ zdaję sobie sprawę, że nie wszyscy znają ten koncept, więc szybkie wprowadzenie. Dalej, dlaczego w ogóle warto z tego korzystać, dlatego dlaczego warto rozważyć ten pomysł. Dalej, wady i pułapki, czyli nie wszystko złoto co się świeci. Feature flagi rozwiązują pewne problemy, natomiast też wprowadzają inne i trzeba o tym wiedzieć. No i na koniec, dobre praktyki, czyli troszeczkę jak zminimalizować te problemy związane z pułapkami. Jakieś podsumowanie, no i czas na Wasze pytanka. Dobra, czym są w ogóle feature flagi? Jakbyście poszukali w internecie, to feature flagi najczęściej są opisywane jako przełącznik. Jest to struktura, a tak naprawdę za chwilę to będzie bardzo proste polecenie w kodzie, które ma nam przełączyć logikę kodu, czyli w danej chwili czasu mamy jedną, jakąś logikę, my ją przełączamy i aplikacja ma działać bardzo często zupełnie inaczej. I co jest istotne, ta zmiana ma nastąpić bez konieczności deploya aplikacji, czyli aplikacja cały czas chodzi na produkcji, użytkownicy z niej korzystają, my przełączamy jakąś flagę i nagle funkcjonalność, aplikacja, widok, tu mamy naprawdę dużą dowolność tego, do czego aplikujemy tę flagę, zmienia swoje zachowanie i użytkownicy będą widzieli tę zmianę. Tu będzie pewnie jakieś przesunięcie w czasie związane z propagacją tej zmiany, natomiast nie mamy opóźnienia związanego z koniecznością zbudowania aplikacji i deployu. Tak to wygląda wysokopoziomowo, natomiast zejdźmy sobie niżej już do kodu. Jeśli pamiętacie, to możemy aplikację oprogramowanie opisywać w postaci takich bloczków. I flaga jest typowym bloczkiem decyzyjnym, ponieważ jeśli flaga spełnia jakiś warunek, który my określimy, to wykonamy kod A, w innym wypadku wykonamy kod B. W kodzie spowoduje się to po prostu do instrukcji IF. Jeśli flaga spełnia jakiś konkretny warunek, który myśmy zdefiniowali, to możemy wyświetlić komponent A, jakiś ekran, logikę, algorytm, w przeciwnym wypadku jakąś inną część naszej aplikacji. I to, co różni takiego typowego IF-a, jakie mamy w kodzie, na feature flagę, to jest to, że ten warunek istnieje w zewnętrznym serwisie. Ta wartość dla tego warunku jest zdefiniowana w zewnętrznym serwisie, najczęściej jest to jakaś aplikacja SaaS, ponieważ rzadko kiedy się to implementuje samemu, nie ma na to czasu, biznes jest ważniejszy. Ja też bardzo często określam feature flagi jako IF as a service, bo to jest dokładnie to, co one robią. One dostarczają nam warunki do IF-ów i te warunki utrzymamy sobie po prostu gdzieś w chmurze. Wiemy, jak mniej więcej to działa. Wysokopoziomowo, nisko, ogólnie wiemy, że to jest IF, rozgałęzienie w kodzie i na podstawie jakiegoś warunku decydujemy, co mamy tam wyświetlać, procesować i tak dalej, natomiast ważne jest pytanie, po co w ogóle nam to. Najważniejsza funkcjonalność to jest wypuść teraz, aktywuj potem, czyli my sobie pracujemy, ukrywamy jakąś funkcjonalność za właśnie flagą, merżujemy do głównej gałęzi i czekamy na odpowiedni moment, żeby to aktywować. Żeby docenić to, co mówię, przypomnijmy sobie taki mało znany koncept, jakim jest Git Workflow. Czyli tak, mamy naszą gałęź main, która jest gałęzią produkcyjną, czyli musi się zawsze budować tak, żebyśmy o drugiej w nocy, w Sylwestra, byli w stanie zbudować na podstawie tej gałęzi produkcję, jakby się serwery spaliły. Czasem fala tam jakiś hotfix, czego nie chcemy raczej. No i z tego maina ląduje nam develop. I develop to jest ulubiona gałąź wszystkich naszych programistów. Dlaczego? Bo to na niej pracujemy przez 99% czasu. To jest gałąź, do której my dokładamy nowe rzeczy. Jak dokładamy? Najczęściej tworząc osobnego brancza z featurem, sobie na nim dziubiemy dzień, dwa, nie wiem, tydzień, cały sprint, dwa, trzy sprinty. Wszystko zależy od tego, jaka to jest funkcjonalność. No i jak mówimy, że funkcjonalność jest gotowa, mergujemy do developa i raz na jakiś czas mamy okienko wydawnicze, gdzie mergujemy developa do mastera. Superfajnie, tylko najczęściej, jeżeli za długo trzymamy, to merge wygląda w ten sposób. I nie wiem, jak Wy macie doświadczenie, natomiast mnie się już zdarzyło parę razy sytuacja, gdzie musiałem rozwiązywać konflikty, bo kolega z zespołu coś wcześniej wmerżował i akurat pracowaliśmy na podobnych plikach. Najgorsza sytuacja jest wtedy, kiedy Wy w GitHubie, GitLabie, czy czego tam używacie, macie ustawione, że kod musi być zawsze zrebazowany do aktualnej wersji. Wtedy następuje coś, co ja nazywam wyścigiem przy merżowaniu, ponieważ Wy się rebazujecie, rozwiązujecie konflikty. Klikacie merge, żeby się zrobił po testach, tylko kolega był szybszy, więc on zdążył się zmerżować. Wy musicie się znowu rebazować, nie daj Boże znowu rozwiązywać konflikty. Jak macie pecha, to będziecie w ten sposób rebazować wszystko przez cały dzień. Jakie mamy inne podejście? Istnieje coś takiego jak trunk-based development. Tutaj mamy jedną główną gałąź produkcyjną i bardzo krótko żyjące gałęzie boczne. One mają być dosłownie krótko żyjące. One mają maksymalnie dzień, dwa, a tak naprawdę dobrze by było, żeby to była kwestia godzin. Czyli tworzymy jakąś funkcjonalność i od razu ją merżujemy. Tylko tutaj musimy pamiętać, że muszą być dwa warunki, żeby w ogóle wprowadzić coś takiego. Po pierwsze testy. I testy faktycznie muszą być uruchome na CIA, tak żebyśmy mieli pewność, że jak coś merżujemy, to nie zepsujemy sobie produkcji. I druga rzecz to jest właśnie feature flagi. Czyli budujemy jakąś funkcjonalność, ukrywamy ją, żeby nie była widoczna dla użytkownika końcowego i domerżowujemy kolejne jakieś elementy tej funkcjonalności tak długo, aż ona jest skończona i dopiero wtedy wpuszczamy użytkowników. Więc tak, co nam odpada? Po pierwsze konieczność synchronizacji feature brancha z mainem. Im dłużej trzymamy ten feature branch z daleka od developa czy maina, tym więcej różnic się tworzy i tym większa musi być synchronizacja, więcej błędów musimy rozwiązać. Dalej konflikty w kodzie, duże PR-ki też nam jakby znikają, ponieważ jeżeli będziemy stosować się do tego, że to mają być małe zmiany, które mają być często implementowane, to też sama PR-ka będzie bardzo mała. No jak wiemy, jeżeli PR-ka ma 10 linii, będzie 10 komentarzy. W przypadku PR-ki, gdzie jest 100 linii, mamy 1 komentarz i najczęściej jest to jakiś dopisek pod tytułem zmień nazwę tego testu. Więc automatem też kod będzie miał tę wyższą jakość. Co dostajemy dodatkowo? Łatwiejsze zmiany w całej aplikacji. W sytuacji, kiedy cały kod żyje w tej jednej gałęzi, a boczne są krótko żyjące, czyli umówmy się, na przykład powstały dzisiaj rano, to na przykład jak podniesiemy wersję bibliotek, no to aktualizacja tego na tych branczach pobocznych będzie dosyć szybka, a bardzo często tam nie będzie wiele zmian. Drugie, nowa funkcjonalność zawsze zsynchronizowana z innymi zmianami i to jest coś, co często widzę na przykład na frontendzie. Czyli jeden zespół tworzy sobie jakiś komponent. Załóżmy, że to będzie komponent tabeli. Jest on najczęściej jednym z najbardziej skomplikowanych. Mamy tabele, wyświetlanie danych, sortowanie, filtrowanie, jakieś wyszukiwanie. Bardzo często jest to dosyć potężny komponent. I jakby mają funkcjonalność, najpierw zbudowali sobie właśnie tabelę, budują wreszcie funkcjonalności i przychodzi drugi zespół, który mówi, hej, słuchajcie, w sumie byśmy wykorzystali ten komponent, bo my już mamy dane gotowe i chcielibyśmy je wyświetlić w ten sposób. No i w zależności od tego, jak zespół pracuje, to mamy kilka opcji. Pierwsza, mamy farta, oni wcześniej zrobili komponent, wmerżowali go do mastera, można użyć. Opcja druga, nie mamy szczęścia. I ta tabela, ten komponent ciągle żyje sobie w osobnym branczu. No i co teraz? Mamy kilka opcji, albo zespół porzuci, ten pierwszy zespół spróbuje szybko wmerzować tą tabelę. Możemy wykorzystywać jakieś sztuczki w postaci cherry picka. Ewentualnie jakby zespół drugi sobie powie, że oni nie mają czasu czekać i oni sobie zbudują drugą tabelę i potem ją zsynchronizujemy do komponenty. Zazwyczaj ta synchronizacja nigdy nie następuje i mamy nagle dwa komponenty tabeli i nikt nie pamięta dlaczego. Pół aplikacji korzysta z jednej, pół z drugiej. Ogólnie koszmar, jeśli chodzi o testowanie i utrzymywanie. Trzecia rzecz, coś, co ja nazywam sytuacją Black Friday. Idealnie się składa w czasie. Sytuacja, kiedy biznes chce na produkcji konkretne funkcjonalności, bo ich potrzebuje, np. zbliża się Black Friday, mamy poprawki konieczne, np. żeby użytkownicy mogli szybciej dostawać swoje zakupy, natomiast w całej paczce na Developie mamy też zmiany, które są aktualnie dosyć ryzykowne. Biznes nie chce specjalnie ryzykować przed Black Friday, że coś pójdzie nie tak. Znowu sytuacja z życia. Miałem projekty już na szczęście dawno temu, gdzie dosłownie klient czasami przychodził i mówił, że fajnie, fajnie, ale w sumie teraz na mastera byśmy wypuścili funkcjonalności A, C, E i F, a tamte na razie zostawcie, bo na razie ich nie chcemy. Tutaj znowu albo bierzemy Developa, usuwamy branż, jakby tamte zmiany, albo tworzymy nowy Merge Request, znowu ponownie te zmiany. Ogólnie jest to proces czasochłonny, dużo błędów potrafi powstać przez przypadek itd. W przypadku Feature Flag, włączamy, wyłączamy w zależności od potrzeb. Przycisk bezpieczeństwa, czyli tzw. piątek, godzina 17. Wypuściliśmy nową wersję aplikacji i się okazało, że np. baza danych na produkcji zawiera dane, których się nie spodziewaliśmy, bo na stagingu np. mamy jakieś niekompletne dane, nie przetestowaliśmy jakiegoś jednego przypadku, on występuje na produkcji i akurat na naszej funkcjonalności to się wysypało. W przypadku, kiedy mamy faktycznie te Feature Flagi, to tak naprawdę możemy to wyłączyć. Czyli w przypadku takim tradycyjnym bez flag, robimy deploy, widzimy, że jest błąd i w zależności od tego, jaki to był deploy, czasami możemy go cofnąć i od razu będzie naprawione, czasami cofnięcie może być niemożliwe, np. w tym deployu były jakieś zmiany na bazie danych, których nie wiemy np. jak cofnąć albo samo cofnięcie tych zmian zajmie jakiś czas i tutaj jakby czas, jak aplikacja nie działa, może się przesunąć do godzin czy nawet dnia. W przypadku Feature Flagi tutaj wchodzimy tam na panel do zarządzania, wyłączamy flagę i aplikacja wraca do życia, bo np. korzysta ze starego widoku, który był korzystany już przez dwa ostatnie lata i wiemy, że on jest stabilny. Dalej, warunkowy dostęp. Bardzo często w tych aplikacjach do zarządzania, tworzenia flag możemy definiować bardzo różne warunki na podstawie użytkownika, czyli wiemy np. że użytkownik z takiego kraju ma wybrany taki język, takie ustawienia, możemy mu np. serwować takie canary deployment, czyli np. nowe funkcjonalności, użytkownik zgadza się, żeby być naszym królikiem doświadczalnym i dostawać nowe rzeczy do testowania za darmo, jakieś kwestie typowe, językowe, np. mamy nową stronę, nową funkcjonalność, tylko jeszcze nie mamy gotowych tłumaczeń dla części treści i chcemy np. ukryć całą stronę dla użytkowników, którzy nie mają języka angielskiego, a w międzyczasie zespół do spraw języka tłumaczy kolejne rzeczy i jak oni mówią, że np. mamy gotowy hiszpański, to my też wyłączamy dla hiszpańskiego. Jeżeli mówi, mamy gotowy francuski, to też wyłączamy dla francuskiego i to wszystko się dzieje bez konieczności deploy'u aplikacji. Developerzy bardzo często nie muszą o tym wiedzieć, że zaszła zmiana w językach, nas to nie interesuje. Tak samo jakieś zmiany prawne, np. jakaś funkcjonalność nie jest mile widziana w jakimś kraju, jest zakazana itd., to też tu może na tym etapie to skonfigurować. Dalej, takie pomniejsza funkcjonalność to jest zdalna konfiguracja, flagi to nie muszą być tylko wyrażenia typu boolean, ale również mogą być stringi, obiekty, tablice, liczby. Możemy w ten sposób konfigurować na żywo naszą aplikację. Następna rzecz, którą bardzo lubię, czyli canary deployment i zanim opowiem, jak to wygląda w przypadku flag, to szybkie przypomnienie, jak to wygląda od strony takiej devopsowej, czyli canary deployment. Mamy naszą aplikację, która już tutaj działa na produkcji, jest stabilna i wydajemy nową wersję. No i nie chcemy od razu przerzucać wszystkich użytkowników, bo nie wiemy, czy to jest stabilne. No to robimy w ten sposób, że większość ruchu puszczamy na stary, natomiast część użytkowników puszczamy na nowe wersje i patrzymy, czy jest stabilne. Jeżeli jest stabilne, no to zwiększamy ten ruch tak długo, aż wersja canary stanie się tą wersją stabilną. Jeżeli wystąpi jakiś błąd, po prostu przekierowujemy użytkowników z powrotem do wersji stabilnej i nie mamy tutaj tak naprawdę żadnego downtime, ponieważ ta wersja stabilna cały czas istnieje. A jak to wygląda w przypadku FeatureFlag? Możemy to zrobić na poziomie pojedynczej funkcjonalności, czyli załóżmy, że mamy jakiś tam u nas w aplikacji proces rejestracji na jakieś tam wydarzenie i mamy formularz, który działa już od dwóch lat, wszystko fajnie działa, ale przyszedł nowy UX designer i powiedział, że on przejeżdżał wszystkie tam aplikacje Airbnb, nie wiem, Booking.com i tak dalej i on wie, jak to zrobić najlepiej i proponuje nowy formularz. Okej, no to my to tam klepiemy, no i wypuszczamy nowy formularz i puszczamy tam na razie część użytkowników, patrzymy, czy nie pojawiają się jakieś błędy, czy zbieramy poprawnie wszystkie dane, czy wszystko jest stabilne, czy nie pojawiają się błędy w jakichś niespodziewanych miejscach. Reszta użytkowników widzi stary formularz, jeżeli wszystko jest okej, no to stopniowo przenosimy użytkowników do nowej wersji, a wkrótce starą wersję będziemy mogli usunąć. No i tutaj od razu przykład bardzo podobny, to są testy AB, czyli sytuacja bardzo podobna, wtedy są podział 50 na 50 i patrzymy, która wersja jest przyjaźniejsza dla użytkownika, przynosi więcej pieniędzy, na przykład w przypadku koszyków internetowych, jak szybko użytkownik zakończył transakcję, czy dokupił sobie coś nowego, czy zapisał się na newsletter i tak dalej. Najczęściej testy AB trwają jakiś czas, miesiąc, dwa miesiące i po tym czasie zbieramy wyniki eksperymentu i decydujemy się na jedną z wersji. Dobra, natomiast to nie jest tak, że to są same zalety, ponieważ gdyby tak było, to wszyscy by z tego korzystali. Flagi rozwiązują pewien zestaw problemów, natomiast wprowadzają inne. Pierwszy problem i taki najpoważniejszy to jest uzależniają i to bardzo. I to zarówno ludzi od strony biznesu, jak i nas, programistów. Biznes, dlaczego? No bo przypomnijcie sobie, przed chwilą mówiłem o tym, że możemy włączać i wyłączać funkcjonalność właściwie na zaobołanie i nie potrzeba do tego żadnego deployu. Umówmy się, jest to spełnienie marzeń każdego biznesu, żeby mogli sobie wprowadzać zmiany w aplikacji i nie musieli prosić programistów o deploy nowej wersji. Na przykład w przypadku tych języków i treści. No to biznes wie, ok, skończyliśmy tutaj wersję język chiński, chcielibyśmy to wprowadzić, bo fajny tam rynek, dużo hajsu, a programiści mówią, że w sumie ten, tylko nie ma teraz ludzi, jest w sumie piątek, 17, to może w poniedziałek jedna osoba doda ten jeden język do tego IFA i potem zrobimy deploy. A tak biznes sobie weźmie, wyklika, że jeszcze włoży dla chińskiego i tyle, nawet programiści o tym nie wiedzą. Z naszej perspektywy zabezpiecza nas to przed błędami, mamy tendencję do takiego dodatkowego zabezpieczania się, czyli dajmy więcej sobie flag po to, żeby można było w razie problemu je wyłączyć. Natomiast jest to błędne myślenie, ponieważ flagi wprowadzają dług techniczny i to spory. Tak jak wspominałem na początku, flaga to jest warunek IFA i on wprowadza rozgałęzienie w kodzie. Rozgałęzienie w kodzie z samej zasady jest problemem, ponieważ powoduje, że musimy pamiętać o dwóch wersjach aplikacji, musimy wiedzieć, że aplikacja dla jednego warunku zachowuje się na przykład inaczej i bardzo często musimy wspierać obie wersje. Wszystko by było fajnie, gdyby to wyglądało w ten sposób. No to da się wspierać. Natomiast z doświadczenia wiem, że jak już jest tak, to za chwilę będzie w ten sposób, a bardzo często kończy się w ten sposób. Problemem jest to, że tego nie widać tych połączeń, bo pomiędzy każdym poziomem na przykład jest pięć innych ekranów i dopiero w momencie, kiedy wystąpi błąd, my wiemy, że ojaj, chyba gdzieś tu są flagi źle zdefiniowane i użytkownik nam gdzieś utknął. Dlatego założenie, im mniej flag w systemie, im mniej rozgałęzień, tym lepiej dla nas, mamy mniej kodu do utrzymania. Okej, błędy i ślepy zaułki. Tak jak tutaj widać, im więcej mamy tych flag, tym więcej mamy ścieżek w aplikacji, w związku z tym więcej możliwości, żeby gdzieś wystąpił błąd. I to jest problematyczne też z tego względu, że powtórzenie błędu może wymagać od nas dokładnie takich samych wartości flag, ponieważ kombinacja flag może powodować, że użytkownik na przykład gdzieś ominął jakiś ekran i nie wprowadził danych i 10 ekranów później to powoduje błąd. To powoduje, że takie aplikacje są naprawdę ciężkie do testów. I tutaj z dwóch powodów. Po pierwsze, tak jak mówiłem, musimy wiedzieć dokładnie, jakie flagi trzeba aktywować, żeby dojść do danej funkcjonalności. Drugi problem wyniknie w organizacjach, gdzie są jakieś problemy na tej linii komunikacji. W sytuacji, kiedy nie mamy flag i mamy testera w projekcie, to oni często robią jakieś testy eksploracyjne, po prostu przeklikują się przez aplikację i sprawdzają, czy wszystko działa. I jeżeli dodamy jakąś nową funkcjonalność, to tester przyjdzie do nas z hasłem, hej, słuchajcie, tutaj jest nowa sekcja, jej nie było wczoraj. Co się stanęło? A, w sumie zapomnieliśmy ci powiedzieć, dodaliśmy tutaj nową funkcjonalność, tutaj masz taski gotowe do testów. Dobra, nic się nie stanęło, jakby zostało wykryte wcześniej. Natomiast w przypadku, kiedy ta sekcja jest ukryta za flagą, to tester jej nie zobaczy, dopóki nie będzie miał właściwej konfiguracji flagi. I bardzo często jej nie znajdzie do momentu, aż to wyjdzie gdzieś na produkcję, gdzie się znajdzie błąd. Ponieważ jeżeli nikt z zespołu mu nie powie o tym, że istnieje taka funkcjonalność i nie da mu odpowiedniej flagi na jego użytkowniku, no to tester nie ma jak znaleźć tej funkcjonalności. Więc tutaj trzeba bardzo się przychodzić do testów i zwrócić na to uwagę. I jeszcze jedna kwestia, to są testy end-to-end. Nagle mamy dużo więcej ścieżek w aplikacji do testowania i musimy zdecydować, które testujemy, bo nie jesteśmy w stanie przetestować wszystkich. Dobra, więc teraz co nieco na temat dobrych praktyk, które minimalizują rzeczy, o których mówiłem wcześniej. I są to praktyki, które my wdrażamy cały czas w zespole, bo spotkaliśmy się z właściwie wszystkimi problemami, które przed chwilą wymieniłem. I zacznę od czegoś nam dobrze znanego. Cytat, że w programowaniu są ciężkie tylko dwie rzeczy. Inwalidacja kesza i nazywanie rzeczy. Keszem się nie będziemy zajmować, natomiast nazewnictwo w przypadku flag ma kolosalne znaczenie. Dlaczego? Ponieważ jeżeli mamy ifa, takiego lokalnego zwykłego w kodzie, to oprócz tego, że mamy ifa, mamy też cały kontekst pliku. Więc wiemy, że na przykład jeżeli to jest klasa uzera, no to if enabled, wiemy, że chodzi o uzera. Jesteśmy w stanie się domyślić, że chodzi o to, czy użytkownik jest aktywny. Natomiast chciałbym znaleźć osobę, która jeżeli ma feature flagę nazwaną enabled, będzie wiedziała, o co chodzi. O użytkownika, o placówkę, jakiś proces, zamówienie. To może być cokolwiek. Dlatego nazwy flag muszą być bardzo precyzyjne i jednoznaczne. Nie możemy sobie tutaj pozwolić na jakieś domysły. Kolejna rzecz to jest coś, na co mam osobiście alergię, czyli konwencja hide feature A, disable feature A. Ja to nazywam, są dwa podejścia, bo możemy albo faktycznie ukrywać coś, albo pokazywać. Natomiast flagi, które mają właśnie pokaż coś, aktywuj coś, a właściwie pokaż, że się jest aktywowane, no to łatwiej jest dla naszego mózgu coś takiego przetworzyć. Szybki przykład. Mamy jakiś tam kawałek kodu, logiki i teraz. Jeżeli nie ukrywamy ekranu A i jest aktywny dla nieangielskich użytkowników, no to zrób coś tam. Już samo powiedzenie, że nie jest ukryty, mamy już dwa przeczenia. Zaczyna się to robić skomplikowane, a bardzo często możemy mieć tutaj na przykład więcej takich warunków. Z drugiej strony mamy, jeśli mamy pokazać ekran A i jest aktywny dla nieangielskich użytkowników, no to zrób coś tam. Dużo łatwiej jest wywnioskować, jaki będzie wynik tego IFA i też nie marnujemy tyle zasobów, jeśli chodzi o mózg. Tak więc odradzam jakieś tam właśnie korzystanie z hide, disable i raczej te wszystkie pozytywne. Jeszcze jedna rzecz, na którą trzeba bardzo zwrócić uwagę, to żeby jak mamy różne środowiska, na przykład mobile i web, to żeby te flagi się nazywały identycznie, bo też spotkałem się już z sytuacją, gdzie na webie było hide screen A, na mobile było show screen A. Obie flagi miały dokładnie tą samą wartość, w związku z tym się wyświetlały użytkownikom różnie w zależności od platformy i po pół roku po prostu musieliśmy szukać informacji o tym, jaka powinna być wartość i tiketu, gdzie to było zaimplementowane itd. Wprowadza to wiele problemów, dlatego lepiej ustalić jedną konwencję nazwniczą i proponowałbym jednak ten show. I co jeszcze można w takiej nazwie flagi dodać? Nazwę zespołu, jakiś skrót, to od razu pokazuje, kto jest odpowiedzialny za to, kto ma wiedzę na ten temat. Czas życia, na przykład rollout, czyli wiemy, że ta flaga powstała tylko po to, żeby wypuścić funkcjonalność i za miesiąc ona będzie usunięta. Platforma, jakieś może środowisko, tutaj zależy jakie mamy platformy i jak ona rozwiązuje np. kwestie środowiska dewowe, produkcyjne itd. I tutaj np. platforma, czyli np. webmobile backend, to znowu pozwala szukać tej flagi, gdzie mamy szukać informacji, czy jest dalej wykorzystywana i też w przyszłości usunąć. Nazwa czasami to nie wszystko, dlatego warto też dodawać jakiś opis. I teraz znowu, w zależności od tego, czy nasz SAS pozwala na dodawanie jakichś opisów, albo możemy typowo oldschoolowo wziąć Excela, Google Sheets i dopisać informację. No to po pierwsze, nazwa flagi, żeby można było ją znaleźć. Jaki jest zespół odpowiedzialny? Czyli znowu, kto ma tę wiedzę na temat tej flagi, po co została wprowadzona, kiedy może być usunięta. Zadanie w JIRA i tutaj tak naprawdę będą dwa zadania. Pierwsze, które wprowadzało tę flagę i w JIRA powinien być opis, dlaczego to jest wprowadzane. Drugie, powinniśmy od razu też stworzyć zadania na usunięcie flag. W momencie większość, 90% flag to będą flagi krótko lub średnio długo żyjące, w związku z tym one powinny być też regularnie usuwane. Więc dobrze jest sobie na przykład stworzyć zadanie na usunięcie i zapisać wszystkie informacje na temat tej flagi, które wiemy w momencie tworzenia, czyli ta flaga istnieje w tym pliku, w tym pliku, w tym pliku i w tym pliku. Przed usunięciem trzeba sprawdzić to, to, to i to w bazie, czy na przykład już jest aktywowane dla wszystkich. Spodziewany czas życia, czyli kiedy ta flaga będzie mogła być usunięta. I tu bardzo przykład na przykład, że wprowadzają funkcjonalność 1 grudnia, wszyscy użytkownicy będą ją widzieć 1 stycznia i od tego czasu dajemy sobie miesiąc czasu, żeby sprawdzić, czy wszystko jest stabilne, czy nie mamy jakiejś rekresji. I od najwcześniej, 1 lutego można zacząć proces usuwania i inne notatki, które pomogą Wam potem przy usuwaniu. No i dokumentacja, dokumentacja, natomiast dobrze jest czasami zajrzeć do tej listy. No i co warto sprawdzić? Po pierwsze, czy mamy wszystkie flagi, czy jakaś flaga nam się nie zgubiła, którą wykorzystujemy, natomiast jej nie ma w dokumencie. Czy są dobrze opisane, czyli czy wszystkie warunki, które myśmy określali, są stworzone. I te są najważniejsze punkty, czyli potrzebujemy każdą flagę. Może już jakaś flaga jest niepotrzebna, może się zmieniły warunki biznesowe, może się test AB skończy. I które flagi można usunąć? Tutaj to jest najważniejsze pytanie, jakie można sobie zadać przy flagach. Nie jaką flagę możemy dodać, tylko co możemy usunąć. Ponieważ każde usunięcie flagi usuwa nam rozgałęzienie w kodzie. I w zależności jak długo to rozgałęzienie istniało, no to tam się nawarstwiła masa kodu. Jeżeli my i tak nie używamy tej części kodu, ponieważ tak na przykład od jakiegoś czasu wszyscy wykorzystają z nowej wersji, to ta część już jest martwym kodem, tam nikt nie zagląda. Natomiast bardzo często przy wprowadzaniu nowych rzeczy, my możemy o tym nie wiedzieć i wprowadzać rzeczy w obu miejscach, bo na przykład nie możemy założyć, jeżeli kod istnieje, że on nie będzie wykorzystany, ponieważ zawsze może być ta sytuacja, że jeszcze możemy być w tym etapie, żeby zrobić rollback. Więc my na przykład musimy utrzymywać oba rozgałęzienia. A w przypadku, kiedy możemy faktycznie usunąć i bardzo często przekonamy biznes, że tak, usuwamy, to jest stabilne, jakby tamtej części nie potrzebujemy, nie potrzebujemy się wracać, no to bardzo dużo kodu może zostać usunięte, co nam czyści tę całą aplikację i usprawnia cały proces. Dalej, zainwestuj w logowanie. To jest punkt, który powinienem właściwie przesunąć na początek, ponieważ bez dobrego logowania informacji na temat tego, co się dzieje w aplikacji, nie ma co podchodzić do implementowania flag. Na froncie mamy centry, na back-endzie data doc i inne rozwiązania, tutaj na back-endzie jakby sporo różnych rozwiązań dotyczących logowania i jest to konieczne, ponieważ my musimy wiedzieć, co się dzieje w aplikacji. Już nie wystarczy nam informacja, że użytkownik widział błąd tam na stronie XYZ, ponieważ w przypadku, kiedy mamy flagi, to on do tej strony XYZ mógł dojść na kilka, kilkanaście innych sposobów. My musimy wiedzieć przy każdym błędzie, jakie dokładnie flagi i wartości użytkownik miał w danym momencie wystąpienia błędu, ponieważ to jest jedyna opcja bardzo często, żeby wykryć błąd i móc odtworzyć ten błąd lokalnie, ponieważ pamiętajmy, najczęściej deweloperzy mają swoje konta zrobione poprawnie, ponieważ jak my pracujemy nad funkcjonalnością, to my z automatu konfigurujemy je tak, żeby u nas happy path działał, dlatego bardzo często my nie jesteśmy w stanie powtórzyć takich błędów u nas lokalnie, bo może wynikać czasami dosłownie z jednej flagi, która gdzieś była kiedyś źle ustalona. Użytkownik jakoś dziwnie wpadł w jeden warunek, dostał jakąś flagę i teraz tą flagą sobie żyje. Ta flaga na przykład może powodować problemy, bo na przykład omija jakiś ekran, który wprowadza ważne dane, których potrzebujemy dalej. Dalej, naucz się odmawiać. To jest według mnie najważniejsza umiejętność, jaką trzeba sobie wyrobić, jeżeli chcemy wprowadzić feature flagi, czyli nie zawsze się nam opłaca wprowadzić flagę do systemu. Nie zawsze jest to opłacane dla systemu, nie zawsze będzie to miało pozytywne skutki, dlatego zanim dodasz nową flagę do systemu, zastanów się czy warto. Jeżeli robimy nowe funkcjonalności, które wiemy, że na przykład zajmą jakiś dłuższy okres czasu, to warto wprowadzić, bo dzięki temu możemy merge'ować na bieżąco, możemy w razie czego wyłączyć tę funkcjonalność. Natomiast jakieś wprowadzenie na przykład nowego tekstu, zmiana koloru, podmiana komponentu batona z jednego przycisku na inny, to nie są zmiany, które będą powodować błędy. Jeżeli spowodują błąd, to będziesz widział to od razu, więc też nie ma sensu się przed tym zabezpieczać tak naprawdę specjalnie. Tutaj zostawmy sobie flagi dla faktycznie tych rzeczy dużych, rzeczy, które mogą nam się zepsuć, które mogą mieć bardzo duży wpływ na aplikację, a tak naprawdę na biznes, natomiast nie wprowadzajmy tego niepotrzebnie. Przechodząc powoli do podsumowania, co warto zapamiętać? Po pierwsze zalety, czyli wypuść teraz, aktywuj później, możemy na bieżąco merge'ować wszystko do głównej gałęzi i aktywować na produkcji dopiero wtedy, kiedy będzie gotowe zarówno od strony programistycznej, jak i od strony biznesowej. Dalej przycisk bezpieczeństwa, nie działa, wyłączamy, mamy czas, żeby spokojnie przejrzeć się, dlaczego nie działa. Dostęp warunkowy, czyli tutaj możemy warunkować jakiś dostęp do pewnych części systemu. Zdalna konfiguracja, canary deployment, czyli możemy wypuszczać funkcjonalność krok po kroku dla pojedynczych użytkowników, którzy wyrazili zgodę w aplikacji na to, żeby dostawać nowe wersje i sprawdzamy, czy działa i stopniowo zwiększamy ilość użytkowników, czy testy AB, kiedy chcemy sprawdzić, które rozwiązanie jest lepsze, lepiej działa. Wady, po pierwsze uzależniające, jak już raz zaczniemy z tego korzystać, to bardzo ciężko jest przerwać, ponieważ jest to bardzo wygodne rozwiązanie, bardzo przyspiesza ten development, natomiast ma swoje minusy, wprowadza dług techniczny. Tutaj mamy sporo ifów w kodzie, które musimy pamiętać, musimy obsługiwać, które produkują dużą ilość kodu. Błędy, ślepe zaułki. Im więcej mamy tych dróg, po którym użytkownik może chodzić, tym więcej szans na błędy w porównaniu z jedną właściwą ścieżką. No i ciężkie do testów, do debugowania. Nie możemy powiedzieć dokładnie, jakie są warunki dla flag, żeby móc się dostać do danej funkcjonalności, żeby odtworzyć błąd. Powoduje to problemy testów end-to-endowych, testów manualnych itd. Natomiast możemy to minimalizować. Po pierwsze inwestycja w dobre nazwy, czyli przeglądamy kod, wiemy od razu, co dana flaga robi, dlaczego została stworzona, co tutaj robi, czy nawet do kogo się odezwać, do jakiego zespołu. Nie używamy hide-disable, ponieważ to niepotrzebnie spala proces skupienia w naszym mózgu. No a lepiej to sobie zostawić na rozwiązywanie typowo problemów programistycznych. Stwórz jakąś zespolę, konwencję do nazywania, żeby te flagi miały właściwe nazwy, właściwą strukturę i trzymajcie się jej. Opisujcie flagi. Im więcej dacie informacji sobie na temat tej flagi, tym łatwiej będzie panować nad tym, ponieważ to nie jest problem dodać flagę, problem jest z nią usunąć. I to bardzo często jest dużo dłuższy czas, żeby usunąć tę flagę, ponieważ trzeba sprawdzić, jakie warunki są, jak rozwiązać ify itd. Rób regularne audyty, sprawdzaj, jakie flagi można usunąć i usuwaj je. Priorityzuj tę pracę, to tylko Ci pomoże w rozwijaniu kolejnych funkcjonalności. To, co jeszcze tam wspominałem, czyli właśnie usuwaj i musisz wprowadzić naprawdę system logowania tych informacji, tak żeby mieć te informacje o tym, jakie flagi miał użytkownik, żeby móc odtworzyć błąd. No i najważniejsze, naucz się odmagać. Im więcej razy odmówisz biznesowi i podasz faktycznie, dlaczego nie warto dać tej flagi, to tym też mniej błędów powodujesz u siebie w kodzie. Flagi są fajne, natomiast muszą być wykorzystywane z rozwagą, ponieważ jeżeli nie będziemy nad tym panować, no to rozrostą się do naprawdę bardzo dużych ilości flag i potem ciężko jest nad tym zapanować. Z mojej strony to wszystko. Czekam na Wasze tutaj pytania. Mnie można znaleźć na social mediach, a również na naszym Discordzie TSH i oprogramowanko, więc nawet jeżeli dzisiaj w nocy Wam przyjdzie do głowy jakieś pytanie, to możecie wejść i zadać z rana pytanie. Ja tam siedzę, więc będę też na bieżąco odpowiadał. Super. Dzięki, Olek, za prezentację. Ja Ci dam, już trochę pytań mamy, także na pewno już będziesz miał pytać. Dobra, to lecimy od góry. Damian Tokarczyk zapytał tutaj, czy są gotowe zasoby serwisy do zarządzania Future Flagami? Tak, my korzystamy aktualnie w projekcie z rozwiązania, które się nazywa Launch Darkly. Jakby bardzo fajne rozwiązanie, jakby dostarcza API SDK do wszystkich platform, czyli zarówno web, mobile, backendowcy też korzystają. Można tam tworzyć segmenty użytkowników i tak dalej, tworzyć warunki na podstawie różnych tam wartości, które zbieramy, więc tutaj Launch Darkly polecam, żeby sobie zerknąć, jeżeli chodzi o taki serwis. Tak naprawdę to może być równie bardzo prosta jakaś baza danych, jeżeli nie zależy nam na jakichś zaawansowanych funkcjonalnościach typu klucz-wartość, natomiast taki serwis rozwiązuje sporą ilość problemów. Ok, następne pytanie jest od Tymoteusza Czech. Jaki kod HTTP powinien zwracać endpoint, który jest za wyłączoną flagą? Według mnie w ogóle nie powinniśmy mieć możliwości od strony klienta dostać się do takiego endpointu, czyli skoro jest nowy endpoint, no to ja rozumiem, że na przykład dodaliśmy nowy widok, ten widok też powinien być ukryty za flagą. Skoro ukrywamy coś przed użytkownikiem, to zróbmy to kompleksowo, czyli użytkownik nie powinien móc się dostać do danego miejsca w aplikacji. Bardzo często na przykład wystarczy zablokować to od strony użytkownika UI-a, ponieważ jeżeli użytkownik nie wejdzie do danego miejsca w aplikacji, to też nie wie, że taki endpoint istnieje i nie będzie go odpytywał samodzielnie. Więc tutaj raczej bym nie dopuścił do sytuacji, kiedy użytkownik może zrobić zapytanie do endpointu, który nie istnieje. A skoro nie istnieje, no to on pewnie i tak by wyrzucił jakieś 404. Następne pytanie, jestem tutaj nie wiem od kogo, bo tutaj nie ma podanego imienia, ale czy jeżeli nowa funkcjonalność jest większa i wymaga dodania IP-ów nie w jednym, a w trzech, czterech, pięciu miejscach, co z czystością oraz wydajnością kodu w takim przypadku? Po pierwsze nie powinniśmy aż tak do tego dopuścić, natomiast wiem, jak to wygląda w praktyce i my robimy tak, że najczęściej flagę tworzymy na wejściu do jakiegoś nowego funkcjonalności, czyli w momencie, kiedy użytkownik może na przykład wejść na jakiś ekran nowy flow, to tam ustawiamy flagę i albo go wpuszczamy tam, albo nie. I wtedy możemy za tą flagą dobudowywać pewne funkcjonalności. Natomiast bardzo często jest tak, że my wypuszczamy to i mamy ten okres karencji, kiedy sprawdzamy, czy to jest stabilne i działa, a tam na przykład dobudowujemy kolejne wersje V1, V2, V3. Tutaj warto pilnować tego, żeby po jakimś czasie, jak już wpuścimy na przykład tą funkcjonalność całościową dla użytkowników, usuwać te flagi, które są zbędne. Natomiast są też flagi, które będą długo żyjące, one będą jakieś konfiguracyjne, ponieważ na przykład biznes chce jakimiś parametrami sobie manipulować i one wtedy faktycznie będą żyły bardzo długo. Natomiast w przypadku takich feature flag typowo na release, tutaj zależy bardzo dużo od biznesu, jak bardzo jest to krytyczne, ilu użytkowników to dotyczy, natomiast dłużej niż rok to jest coś nie tak, znaczy, że prawdopodobnie już nie potrzebujemy aż tak dużej flagi i możemy coś usunąć. Super, od razu odpowiedziałeś też na drugą część pytania właśnie o długość, jakie takie flagi, jak długo powinny być na prodzie. Kolejne pytanie jest dokładnie takie same, czyli kiedy usuwamy feature flagi, ale też miałeś dużo o tym w prezentacji, więc myślę, że to już powinno być jasne. Kolejne pytanie też od Mateusz Czech. Bid or buy, polecasz jakieś rozwiązanie? OK, to samo rozwiązanie już tutaj polecałem, a bid or buy, tutaj zależy bardzo wiele od biznesu, ponieważ trzeba zwrócić uwagę na to, że biznes może nie mieć pieniędzy, żeby wziąć programistów, dać jakieś rzeczy, wymagania do tego serwisu, bo to trzeba zbudować, na przykład będą budowali taki serwis rok, potem to trzeba jeszcze utrzymywać, rozwijać i tak dalej. Nagle się okazuje, że na przykład koszt takiego serwisu zewnętrznego, nawet niech on kosztuje tysiąc dolarów miesięcznie, może być nieporównywalnie mniejszy niż koszt tworzenia tego samodzielnie, utrzymywania tego samodzielnie, dopisywania nowych funkcjonalności. Tutaj płacimy, wymagamy i to zupełnie schodzi. Trzeba się zastanowić, czy faktycznie to, co chcemy zbudować, jest takim corem naszym biznesu, czy po prostu to jest coś, co wspiera nasz biznes, w związku z tym my możemy kupić to jako zewnętrzną aplikację. W 90% przypadkach, jeżeli nie tworzymy nowego Sasa do zarządzania flagami, będzie raczej to kupić sobie jakąś subskrypcję i tak dalej i nie przejmować się tym, a korzystać do tego, żeby móc rozwijać aplikację. Super. Dobra, kolejne pytanie też od osoby anonimowej. Jakie są dobre praktyki dla aplikacji wysoce uzależnionych od konfiguracji? Czy powinna być to jedna aplikacja, a konfiguracja per klient, React Lazy, modularyzacja? Jak nie pojść ofiarą ifologii w komponentach? Tutaj trzeba by było tak naprawdę zacząć od samego początku, czyli co to jest za konfiguracja, jakie rzeczy my konfigurujemy, ponieważ czy to jest na przykład tylko konfiguracja, na przykład jakieś kolorki, team i tak dalej, czy już konfiguracja bardziej złożona, bo może jeżeli to jest konfiguracja bardziej złożona, to po stronie front-endu stworzyć coś na zasadzie buildera, czyli my dostajemy z back-endu konfigurację, jak ma wyglądać dany ekran, na front-endzie tworzymy komponenty, no i na podstawie zwrotki z API my będziemy budowali po prostu ten ekran na żywo. W ten sposób jest to bardziej rozwijalne, natomiast tutaj wiele zależy od tego, co to jest za konfiguracja, co ma robić ta aplikacja, i jak daleka ma być właśnie ta różnica pomiędzy jedną aplikacją a drugą dla klienta. Natomiast tutaj, żeby nie wpaść w jakąś ifologię, tutaj już raczej trzeba będzie skorzystać z tych wzorców jakichś projektowych, czy fabryka, czy właśnie budowniczy, po to, żeby móc na podstawie jakiegoś kontraktu czy obiektu konfiguracyjnego zbudować czy to komponent, czy cały ekran. Super, od razu odpowiedziałeś na kolejne pytanie, które właśnie dotyczyło, czy nie ma lepszego pomysłu na te ify. Ok, trzeba się nie użyć jakiegoś wzorca strategii. Super, no i teraz jedno z najważniejszych pytań, jak się wabi kotek? Kotek się wabi koko i muszę powiedzieć, że ona wyczuła idealnie, kiedy zaczynałam prezentację, bo tuż przed prezentacją już się zaczęła kręcić i wybagała dodatkowe jedzenie, żeby sobie poszła się pobawić. Tak, i tutaj jeszcze jest prośba od Katarzynka, że dzięki za świetną prezentację, ale jeszcze tutaj prośba właśnie o powidzianie kotka. Kotelek też dziękuję za prezentację. Super, dobra, pojawiły się jeszcze jakieś dodatkowe pytania, na szybko jeszcze je zadam, bo chyba nie będą aż takie długie. Czy jakieś inne rozwiązania poza LaunchDarkly były przez Ciebie testowane? Nie, aktualnie korzystamy z LaunchDarkly, jesteśmy z niego w pełni zadowoleni i nie mieliśmy potrzeby też testować innych rozwiązań. Dobra, i kolejne szybkie od Dawida Słowińskiego. Gdzie zapisujesz flagi globalne dla wszystkich userów? W envach, TrueFalse, czy jak to robisz? Co znaczy flagi globalne dla wszystkich userów? Jeżeli wszyscy użytkownicy mają dostawać tą samą wartość, to pytanie brzmi, czy warto faktycznie wprowadzać w ogóle flagę, skoro ona jest globalna. Jeżeli to jest jakiś TrueFalse w zależności np. od konfiguracji serwera, np. apiki do serwisów, no to tak, raczej envy, żeby można było to bezpiecznie przechowywać i budować podczas budowania. Więc raczej envy, natomiast tutaj zastanowiłbym się, czy faktycznie potrzebujemy, jeżeli coś jest globalne, faktycznie taką flagę. Dobra, czytam już ostatnio, już nie zadawałeś tych pytań. Jak coś, to możecie pisać później do Olka na Discordzie albo na maila. Dobra, to pytania się ciągle pojawiają. Co w sytuacji, jeżeli feature to nie jest osobny widok, a jest rozsiany po całej aplikacji? Jak w takiej sytuacji użyć feature flagi? Czy możemy uniknąć jej rozsiania po wielu komponentach? Może wtedy warto wyciągnąć jakąś logikę do wspólnego serwisu, np. Custom Hooka, który będzie trzymał tą całą logikę. I będzie zwracał jedną wartość albo drugą. Będzie odpytywał jeden endpoint albo drugi o jakieś informacje. I my będziemy w tych komponentach rozsianych korzystać właśnie z tego Custom Hooka i mamy wszystko fajnie działa, a logikę i IFA mamy zamkniętego w jednym miejscu. Pewnie bym poszedł tutaj w jakiegoś Custom Hooka, czy jakiś serwis, czy klasę. Tak naprawdę tutaj nazewnictwo jest, w zależności od framework'a, natomiast po prostu jeden wspólne miejsce, które jest zainstalowane i my będziemy reużywać tego u innych. Dobra, więcej pytań nie czytam, jeszcze tam jakieś dwa się pojawiły. Napiszcie spokojnie do Olka, tu macie dane Olka, jeśli chodzi o maila, macie linka na Discorda, żebyście mogli go tam złapać. Olek tam jest ciągle, ja nie wiem, kiedy on śpi czasami. Ale Olek, ja bym miał jedno pytanie jeszcze z tych feature flag. A przytrafiło Ci się coś, że niechcący włączyłeś jakąś feature flagę i wysypałeś na przykład na produkcji komuś coś, że użytkownicy nie mogli czegoś konkretnego robić? Na szczęście nie, natomiast parę razy jakby się ogólnie zdarzyło, że coś tam włączyliśmy i na szczęście to potem szybko można wyłączyć, ale nie, tutaj Lampdarki ma to, że dla stagingów to jest tak, zmiana flagi, potem trzeba to jeszcze akceptować, a w przypadku, kiedy to jest środowisko produkcyjne, on chce, żeby od Ciebie, żebyś to chyba wpisał production w polu tekstowym, więc wiesz o tym, że to jest produkcja. Podobne rozwiązanie jak na przykład usuwanie bucketów na S3, że trzeba wpisać nazwę. Na pewno chcesz usunąć bucket tutaj nazwy, to wpiszesz tą nazwę. Gorzej, jak bucket będzie się nazywał, nie chcę. Dobra, super. Olek, dzięki wielkie za prezentację i za odpowiedzi na te liczne pytania.