Tak robiłem taki system. tematy do poczytania to CQRS, Event Sourcing, Message bus, Task Based UI. Następnie aplikujesz to tam gdzie to ma sens i 'da się'.
Po stronie backendu wszystko łądnie można złożyć, jeśli zrobione zostało z głową i jest skalowalne i dośc odporne (chociaż to zwykle trudne tematy swoją drogą). Masz kolejki i ktoś wysyła wiadomość, ktoś(od 0 do wielu innych serwisów) ktoś odbiera, procesuje i może też wysłać swoją. Z punktu widzenia infra to są wiadmości. Z punktu widzenia architektóry to mogą być Commands i Events. Beżstanowośc? Tak, tu trzeba by wiadomości były idempotentne. Trzeba wiedzieć czy dana wiadomośc już była przeprocesowana czy nie i uwzględnić race conditions. Czyli powinna mieć swoje unikalne ID. A co do ID to jeszcze fajnie by było mieć do monitorowania itp itd collerationID i causationID też. Tutaj dużo zależy od danego rozwiązania technicznego też i platformy z której korzystasz. Co masz out of the box, a co musisz dokodzić sam. Np jeśli masz 3 instacje serwisu X, który sunbskrybuje wiadmości z danego topica, to możesz ustawić tzw round robin, i tylko jedna instancja dostanie wiadomość. Albo możesz ustawić żeby dostała każda, jeśli tak ma to działać u Ciebie. Zależy co chcesz osiągnąć. Problem się zaczyna przy unhappy path, co jeśli instacja 1 dostała, ale nie było zwrotki że przeprocesowała? Wtedy trzeba znów wysłać, ale nie wiesz czy wiadomość została przeprocesowana czy nie, gdzie jest problem. I tu właśnie idempotentnośc wiadomości wchodzi w grę, przy tych scenariuszach. Czy to rozwiązuje problem? Tak. Czy łatwo to zaodować... to zależy zwykle nie tak łatwo jak synchroniczną komunikację. Mikroserwisy mają swój koszt, dlatego nie warto ich stosować na ślepo.
Co do punktu widzenia klienta, jeśli to też jakieś API to powinno sobie z tym poradzić, tu mamy różne rozwiązania: może mieć dostęp do tego samego message brockera - i tu sprawa jest prosta. Jeśli to klient zewnętrzny - to znów specjalna widoczna na zewnątrz kolejka dla niego i gotowe. A ze starszych rozwiązań to callbacki czy tfu cykliczne odpytywanie naszego serwsiu po dane(tu warto uważąć żeby nas klienci nie DDOSowali). Nie polecam tego ostatniego.
A jeśli to jest UI?
Są miejsca że nie da się, albo będzie kosztowało więcej wysiłku niż tego jest warte (np jakiś CRUD, albo system który nie potrzebuje super wydajności i skalowalności dla miliona użytkwoników, bo będzie używany przez 30 osób w firmie - ale zwykle wtedy, jeśli chcesz zrobić tzw Task Based UI to uzytkownicy znają procesy w firmie i będzie OK jeśli będą musieli np odświeżyć stronę zeby załądować zmiany, albo pcozekać te kilka sekund na przeprocesowanie czegoś, bo wiedzą że np dodanie nowego kierowcy zajmuje systemowi 15 sekund, bo tworzy mu konta w 10 systemach a potem je aktywuje, wysyła 50 meili z gratulacjami i zaczyna zamawiać kubek z logo firmy u dostawcyy, i dopiero jak to skończy to kierowca będzie na liście).
Tak w dużym skrócie, bo napisano o tym sporo już i ja w jednym poscie tego nie skrócę sensownie:
Przede wszystkim zwykle wystarczy potwierdzenie że serwer przyjął request (np command, nie jest to teraz istotne) i procesuje. Czyli zewnętrznie dostajesz np 200 OK a wewnętrznie wiadomośc trafiła na kolejkę, i koło się kręci. A co się stanie później?
Co do UI i odświeżania, dziś są dostępne rozwiązania jak np google Firebase, które przy zmianie stanu może wysłać powiadomienie do UI, następnie ten UI może się reaktywnie odświeżyć dzięki temu. Stosując CQRS możesz użyć firebase jako bazę do odczytu. Przy Event sorcingu wtedy masz serwis procesujący stream i uaktualniający firebase. Inna opcja to jakieś streamowanie wiadomości do UI żeby ten sobie je odświeżył np przy tzw pizza trackerze. Tu też są gotowe rozwiązania któe działają lub nie z daną platformą (np nie działa na iOS albo Safari, albo gdzieś tam).
To pozwala nieco schować asynchronicznośc na poziomie UI.
Task based UI znów nie potrzebuje takich cyrków zawsze, bo wystarczy potwierdzenie że zostało przyjęte przez serwer. Przykład aukcja została zakceptowana, dostaniesz powiadomienie jak będzie aktywna i dopiero wtedy ją zobaczysz na liście aktywnych jak odświeżysz stronę.
Taki asynchroniczny system zwykle działa bardzo szybko. I o ile nie usiłujesz od razu w danej milisekundzie pokazać odświeżonej strony z aktywnymi, jest szansa że jak użytkwonik kliknie i wróci na np listę aukcji aktywnych to ona już tam będzie. Tu zależy sporo też od procesu biznesowego.