Blog

Czy kolejki zawładną światem?
Z czym kojarzy Ci się kolejka? Podejrzewam, że z niczym przyjemnym. Zwykle czekamy w kolejce do lekarza, w sklepie, na poczcie… I postrzegamy to jedynie jako marnowanie czasu.
Być może będziesz zaskoczony, ale w programowaniu także można spotkać kolejki, działające na podobnej zasadzie jak te w życiu codziennym. Z tą różnicą, że tutaj bardzo pomagają!
Po co stosować kolejki?
Pewnie zastanawiasz się, dlaczego w ogóle stosować kolejki? Otóż dzięki nim możemy wykonywać kilka operacji równolegle, w odróżnieniu od operacji synchronicznych, które są wykonywane tu i teraz. Usprawnia to wykonywanie zadań i zapewnia płynne działanie systemu.
Jednak nie wszystkie zadania możemy realizować asynchronicznie, czyli za pomocą kolejek. Jeśli na przykład klient dodaje produkt do koszyka, ta operacja musi być przetworzona od razu po kliknięciu. Dlatego w tym przypadku lepiej sprawdzi się metoda tradycyjna.
Gdyby natomiast chodziło o sprawdzenie dostępności produktu, tutaj już śmiało możemy wykorzystać kolejkę. Ważne jedynie, aby ta operacja wykonała się przed dokonaniem płatności. Inaczej możemy mieć problem z realizacją zamówienia, co może mieć negatywne skutki dla wiarygodności sklepu w oczach klientów.
Typowym przykładem użycia asynchroniczności jest wysyłka wszelkich powiadomień systemowych, w których system dopuszcza opóźnienia. Dzięki temu możemy zmniejszyć liczbę wykonywanych operacji, a przez to użytkownik szybciej dostanie odpowiedź na swoje żądanie.
Innym przypadkiem użycia kolejek jest wykonanie wielu operacji, które mogą trwać na tyle długo, że użytkownik będzie miał wrażenie, że system się zawiesił albo otrzymał błąd o przekroczeniu czasu na wykonanie żądania.
Limity czasowe skupienia użytkownika
Według Jakoba Nielsena interfejsy mają 3 limity czasowe, gdy użytkownik będzie skupiony na aplikacji.(1)
0,1 sekundy to granica pozwalająca użytkownikowi czuć, że system reaguje natychmiast. Oznacza to, że nie trzeba stosować żadnej dodatkowej informacji zwrotnej, poza wyświetleniem wyniku.
1 sekunda to granica nieprzerwanej płynności działania, nawet jeśli użytkownik zauważy opóźnienie. Zazwyczaj dla opóźnień między 0,1 a 1 sekundą nie są konieczne żadne dodatkowe komunikaty, lecz użytkownik traci już poczucie bezpośredniego działania na danych.
10 sekund to granica skupienia uwagi użytkownika. W przypadku dłuższych opóźnień użytkownicy będą chcieli wykonać inne zadania w oczekiwaniu na zakończenie pracy. Z tego powodu powinni otrzymać informację zwrotną, wskazującą kiedy mogą się spodziewać wykonania operacji. Informacje zwrotne podczas opóźnień są szczególnie ważne, jeśli czas odpowiedzi może być bardzo zmienny, ponieważ bez tego użytkownicy nie będą wiedzieć, czego się spodziewać.
Choć 10 sekund wydaje się bardzo małą wartością, w przypadku systemów informatycznych to prawdziwa wieczność. Tak długi czas oczekiwania niesie za sobą wiele ryzyk. Przede wszystkim spada znacząco aspekt użyteczności aplikacji (co przekłada się bezpośrednio na opinie i ilość aktywnych użytkowników), ale także wykonywanie operacji może zostać przerwane w nieoczekiwanym momencie, co może powodować niespójność danych.
Rodzaje kolejek
Wyobraź sobie, że masz sklep internetowy i dowiadujesz się, że produkt, który sprzedał się w tysiącach egzemplarzy, jednak nie zostanie dostarczony do sklepu. W takiej sytuacji trzeba anulować wszystkie zamówienia.
Z punktu widzenia biznesu, nie ma znaczenia, czy zamówienia zostaną anulowane w momencie kliknięcia przycisku, czy dopiero po kilkunastu minutach. W takiej sytuacji warto skorzystać z kolejki i anulować zamówienia partiami. Usprawni to działanie systemu, a w przypadku błędów, system w łatwy sposób będzie mógł wrócić do wykonywania działań we właściwym momencie.
W powyższym przypadku zamówienia będą anulowane według kolejności, którą wszyscy znamy ze sklepów, czyli — pierwszy w kolejce, zostaje obsłużony pierwszy. Ten model nazywany jest FIFO (First In First Out). Zadania realizowane są po kolei i wyłącznie kolejność dodania do listy decyduje o tym, kiedy dane zadanie będzie obsłużone.
Sytuacja nie zawsze wygląda tak prosto i czasami trzeba wprowadzić w tej kwestii jakieś roszady. Wtedy przychodzi na pomoc model PRIORITY, w którym o kolejności wykonania zadania nie decyduje kolejność dołączenia do kolejki, ale nadany mu priorytet.
Zastosowanie takiej kolejki będzie wymagane w przypadkach, kiedy od wykonania danego działania zależy płynność działania systemu i możliwość wykonania pozostałych zadań. Wówczas takie zadanie priorytetowe musi zostać wykonane w pierwszej kolejności, bez względu na to, kiedy zostało dodane do kolejki.
Nie da się jednoznacznie określić, kiedy zastosować który model kolejki. Z mojego doświadczenia, w większości przypadków wystarczają kolejki FIFO.
Przypadki można mnożyć, ale zawsze warto dopasować użycie kolejek do konkretnego przypadku. Warto skonsultować z biznesem, które operacje mogą być wykonywane asynchronicznie, a które nie, bo inaczej takie rozwiązanie może być super wydajne i zoptymalizowane, a mimo wszystko będzie bezużyteczne.
1 https://www.nngroup.com/articles/response-times-3-important-limits/