Synchronicznie, asynchronicznie?


IT, IT-DLA-ZIELONYCH / sobota, 11 lipca, 2020

Połączenie, komunikacja. Synchroniczna. Asynchroniczna. Wielowątkowość. Multithreading. Być może, któreś z tych słów już miałeś okazję usłyszeć. W dzisiejszym artykule przyjrzymy się im z bliska i rozwiejemy watpliwości.

Jeden wątek

Wyobraź sobie człowieka, który w danym momencie w czasie jest w stanie zająć się tylko jedną rzeczą. Postępuje zadaniowo. Wkłada naczynia do zmywarki. Jedzie na zakupy i stojąc w kolejce do kasy zajęty jest czekaniem na swoją kolej. Wysyła maila, aby pozyskać informacje i czekając na odpowiedź nie robi nic innego dopóki nie uzyska odpowiedzi i nie zamknie swojego zapytania. Jednym słowem działa jednowątkowo.

W podobny sposób może działać aplikacja. Wyobraź sobie, że wprowadzasz parametry do formularza, na podstawie których mają być odfiltrowane i wyrenderowane na diagramie wyniki. Przetwarzanie danych trwa, aplikacja więc na kilkadziesiąt sekund zawiesza się („freezuje się”) i użytkownik ma wrażenie, że coś poszło nie tak. Tymczasem wszystko jest w jak najlepszym porządku, a aplikacja po prostu czeka. W końcu otrzymuje odpowiedź z serwera, dane są przetworzone i gotowe do wyrenderowania (zwizualizowania) po stronie użytkownika. Działa jednowątkowo, a komunikacja przebiega synchronicznie. Czy byłbyś zadowolony z takiego obrotu spraw?

Wiele watków

Ja jako użytkownik z pewnością nie. Konieczne jest więc rozwiązanie tego w inny sposób. Chcemy, aby komunikacja przebiegała asynchronicznie. Jako aplikacja kliencka chcemy po prostu przekazać parametry i zgłosić serwerowi zapotrzebowanie na przetworzenie danych. Pragniemy otrzymać tak przygotowane dane, aby można je było zwizualizować na wykresie po stronie frontendu. Jednocześnie w międzyczasie nie chcemy czekać. Zamrożenie aplikacji (równoznaczne z niemożliwością nawiązania z nia jakiejkolwiek interakcji) jest niedopuszczalne. Użytkownik powinien móc normalnie z niej korzystać, ewentualnie widzieć content loader/spinner sygnalizujący oczekiwanie. Gdy nadejdzie odpowiedź z backendu możemy na nią zareagować i powrócić do rozpoczętej przez użytkownika akcji – zaprezentować mu wykres z odfiltrowanymi danymi.

Jak osiągnąć taki stan? Przede wszystkim korzystając z wielu wątków, stosując multithreading. Wówczas wątek główny aplikacji nie jest zablokowany czekaniem na odpowiedź z serwera. Może w dalszym ciągu obsługiwać żądania użytkownika, być responsywny. Zapytanie, które wymaga dłuższego oczekiwania na odpowiedź jest wykonywane na innym wątku.

Synchroniczność i asynchroniczność w świecie aplikacji

Synchroniczność moglibyśmy również porównać do rozmowy z konsultantem banku na komunikatorze chatu w czasie rzeczywistym. Wysyłamy wiadomość i oczekujemy na odpowiedź. W trakcie, kiedy konsultant lub (coraz częściej) bot komponuje dla nas odpowiedź jesteśmy nadal w procesie w 100% obecni – czekamy.

Aplikacje działając, generują wiadomości, wysyłają żądania do API i mikroserwisów, wywołują funkcje. Przy komunikacji synchronicznej po wysłaniu takiego żądania software pozostawałby w stanie bezczynności. Kod nie wykonywałby się dalej i trwałoby to do momentu otrzymania odpowiedzi na wysłane żądanie.

W przeciwieństwie do tego przy komunikacji asynchronicznej wysłanie żądania nie powoduje zawieszenia wykonywania kodu źródłowego. Aplikacja działa dalej. Przykładem działania asynchronicznego będzie wbudowany firmware drukarki, który potrafi wysłać komunikat o niskim poziomie toneru jednocześnie nie przerywając drukowania.

Podsumowanie

Reasumując mamy dwa rodzaje komunikacji – synchroniczną i asynchroniczną. Zdając sobie sprawę, że skojarzenie ich z jedno- oraz wielowątkowością może nie być oczywiste, przygotowałam dla Ciebie następujace podsumowanie:

Komunikacja synchroniczna = jednowątkowa ( ang. single thread ):

  • (+) Pozwala na przetwarzanie w czasie rzeczywistym
  • (+) Zazwyczaj łatwiejsza do śledzenia potencjalnych błędów
  • (-) Bywa czasochłonna
  • (-) Prowadzi do okresów bezczynności w momencie oczekiwania na wykonanie zadanej czynności/akcji
  • (-) Doświadczenia użytkownika mogą być negatywne

Komunikacja asynchroniczna = wielowątkowa ( ang. multithreading ):

  • (+) Działanie aplikacji nie ejst blokowane przez wysłane żądania i inne wywołania czekające na swoją kolej
  • (+) Wiele czynności może być wykonanych w jednym momencie, co obniża czas oczekiwania użytkowników
  • (-) Czasy odpowiedzi nie zawsze są przewidywalne, nie mamy gwarancji tego, że „nie przejdziemy dalej dopóki nie skończymy”
  • (-) Trudniejsze śledzenie ewentualnych błędów

Oczywiście zupełnie niezależnie od wiedzy ze świata IT, toczą sie dywagacje na temat tego, w jakim trybie lepiej działa człowiek. Multitasking i przełączanie wątków nie wydają się dobrze służyć naszej produktywności. Zastanówcie się, jak na co dzień Wy działacie- jedno- czy raczej wielowątkowo? 😉

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany.