net·devs
← Wszystkie artykuły
File insight
3 min czytaniaAutor: Kyrylo Osadchuklogisticsmobile

Twoja aplikacja dla kierowców musi działać w klatce Faradaya

Oprogramowanie logistyczne zakładające łączność zawiedzie w produkcji mniej więcej trzeciego dnia. Budowanie z podejściem offline-first to nie premium inżynieria — to jedyne podejście, które działa.

Najbardziej przydatne ćwiczenie, jakie przeprowadzamy dla nowego klienta logistycznego, to test windy. Weź telefon kierowcy do windy towarowej przy rampie załadunkowej. Zamknij drzwi. Obserwuj aplikację.

Jeśli aplikacja zamienia się w kółko ładowania, zawiesza się, traci miejsce użytkownika lub — najczęstszy błąd — po cichu gubi skan, który kierowca właśnie wykonał, aplikacja nie jest gotowa do produkcji. Kierowcy spędzają znaczną część dnia w stalowych skrzynkach, betonowych budynkach, martwych strefach wiejskich i tunelach. Łączność nie jest właściwością, którą posiadają. To właściwość, którą czasem posiadają.

To jest rzeczywiste ograniczenie. Budowanie z jego uwzględnieniem to nie premium inżynieria — to jedyny rodzaj, który działa.

Trzy tryby awarii, które dopadają każdy zespół

Po wystarczającej liczbie projektów logistycznych te same trzy tryby awarii pojawiają się wielokrotnie.

Optymistyczny zapis, który nie trafił. Kierowca skanuje paczkę. Aplikacja pokazuje „zeskanowano." Serwer, z powodu chwilowej przerwy w sieci, nigdy nie odebrał skanu. Kierowca wierzy, że paczka jest w systemie; system tego nie wie. Paczka dociera do kolejnego punktu i nikt nie wie, co z nią zrobić. Przyczyna: aplikacja pokazała sukces na podstawie lokalnej akcji, bez potwierdzenia z serwera i bez możliwości, żeby kierowca wiedział, że coś się różni.

Logowanie wymagające sieci. Kierowca pojawia się na początku zmiany, a telefon utracił sesję. Ekran logowania musi zadzwonić do serwera autentykacji. Kierowca jest na parkingu, z dwoma kreskami zasięgu, który spada do zera, gdy ciężarówka się porusza. Zmiana nie może się rozpocząć. Każda minuta to czas płatny, a telefon dyspozytora teraz dzwoni.

Kolejka „zsynchronizuj później", która traci dane. Wiele zespołów buduje wsparcie offline, kolejkując akcje lokalnie i synchronizując przy powrocie sieci. Działa to do momentu, gdy kolejka rośnie ponad pojemność urządzenia, lub użytkownik zamyka aplikację i kolejka jest utracona, lub kod synchronizacji ma błąd i po cichu porzuca elementy. Kierowca wykonuje swoją pracę poprawnie. Dane nie docierają. Kierowca dostaje winę.

Czego offline-first naprawdę wymaga

Offline-first to nie funkcja, którą dodajesz. To właściwość architektury — albo aplikacja jest zbudowana wokół niej od pierwszego dnia, albo nie jest.

Kształt, który działa:

Lokalny magazyn jest źródłem prawdy dla sesji. Gdy kierowca skanuje paczkę, skan jest natychmiast zapisywany do trwałego lokalnego magazynu, a UI czyta z tego magazynu. Synchronizacja z serwerem to oddzielny proces, który uruchamia się gdy może. UI nie czeka na serwer — pokazuje stan lokalny, który jest rzeczywistym stanem doświadczanym przez kierowcę.

Każda akcja ma ID generowane po stronie klienta. UUID-y, generowane na urządzeniu przed wykonaniem akcji. Oznacza to, że tę samą akcję można bezpiecznie ponawiać w nieskończoność bez tworzenia duplikatów po stronie serwera, i że akcja istnieje w lokalnym magazynie ze stabilną tożsamością jeszcze zanim serwer ją zobaczył.

Synchronizacja jest widoczna dla użytkownika, nie ukryta. Mały wskaźnik: „12 akcji oczekuje, ostatnia synchronizacja 4 minuty temu." Kierowcy uważają to za uspokajające. Chcą wiedzieć, czy ich praca została zarejestrowana. Ukrywanie stanu synchronizacji w imię czystości UX prowadzi właśnie do scenariusza „zeskanowano, ale właściwie nie."

Tokeny autentykacji mają długą ważność offline. Zaloguj raz, uzyskaj token, który przeżywa wielodniowy okres offline. Odświeżaj token w tle, gdy sieć jest dostępna. Traktuj błąd sieci przy odświeżaniu tokenu jako zdarzenie bez znaczenia; tylko token, który faktycznie wygasł bez odświeżenia, powinien wymuszać ponowne logowanie. Ta jedna zmiana eliminuje najczęstszą awarię na początku dnia.

Co to zmienia po stronie serwera

Offline-first jest zazwyczaj definiowany jako właściwość po stronie klienta. Ma też konsekwencje dla serwera.

Endpointy serwera muszą być idempotentne. Klient będzie ponawiał. Ponowienia będą się zdarzały dni po oryginale. Oryginał mógł lub nie mógł być odebrany. Endpoint musi obsługiwać „już przetworzyłem tę akcję z tym ID generowanym przez klienta" płynnie — zwracając ten sam wynik zamiast tworzyć duplikat lub odrzucać żądanie.

Czas na serwerze to nie to samo co czas na kliencie. Akcja została wykonana o 9:14 czasu lokalnego kierowcy, ale serwer rejestruje ją o 11:47 po powrocie kierowcy w zasięg. Każdy rekord potrzebuje obu znaczników czasu. Raporty, które je mieszają, będą wprowadzać firmę w błąd.

Kształt danych musi tolerować edycje eventalnie spójne. Kierowca może oznaczyć paczkę jako dostarczoną, a następnie supervisor może oznaczyć ją jako zwrot, zanim akcja kierowcy się zsynchronizowała. Rozwiązywanie konfliktów musi być celowe, nie „ostatni zapis wygrywa przez przypadek." Zazwyczaj zasada brzmi: „akcja kierowcy ma priorytet w trakcie zmiany, akcja supervisora ma priorytet po zmianie" — ale zależy to od biznesu.

Praktyczny test

Jeśli oceniasz platformę logistyczną — kupując lub budując — przeprowadź test windy zanim cokolwiek innego. Weź aplikację, weź telefon, zamknij drzwi windy, wykonaj normalne zadanie. Patrz co się dzieje.

Platformy, które przechodzą ten test, są zazwyczaj w porządku. Platformy, które go nie przechodzą, będą go nie przechodziły w produkcji każdego dnia — i będą obwiniały sieć, gdy to się stanie.

Chcemy poznać Twoje myśli.

nasz CTO Kyrylo Osadchuk odpowie w ciągu 24 godzin. Bez lejka sprzedażowego.