Wątek przeniesiony 2021-05-28 17:21 z Java przez Shalom.

Eventy w Event Driven Development

0

Jak duże powinny być eventy i co powinny konkretnie zawierać?

Załóżmy, że na profilu usera możemy zrobić 3 operacje biznesowe:

  • zmiana zdjęcia
  • zmiana imienia
  • wyczyszczenie obu

Czy tutaj powinienem emitować 3 eventy:

  • image.updated z nowym urlem i id profilu
  • name.updated z nowym imieniem i id profilu
  • profile.cleared z id profilu?

Dlaczego w sumie do takiego eventu nie możemy od razu wepchnąć wszystkich pól z profilu? Wtedy inne mikroserwisy, które trzymają lokalnie kopie obiektu User mogłyby odświeżyć wszystkie pola sobie i naprawić się jeśli w historii ominął je jakiś event?

2

Nie rozumiem czemu "nie można" niby. Jeśli masz event ProfileUpdate z wszystkimi polami to tak jest i tyle. Dzielenie na kawałki ma sens kiedy te kawałki same w sobie mają jakiś sens i np. ktoś chce obsługiwać tylko PhotoChangeEvent bo np. macie auto-skaner który sprawdza czy ktoś nie wrzucił jakiegoś wulgarnego zdjęcia i chcesz ten skaner odpalać tylko jeśli zmieniło się zdjęcie, a nie jak user zmienił email.

1

Dokładnie - najprościej jeden event jedna "akcja" użytkownika. Czyli jakiś jeden submit to wychodzi jeden event (to oczywiście uproszczenie, ale 80% przypadków pokrywa).

Generalnie typów eventów jest zwykle dużo mniej niż się ludzie spodziewają - całkiem spore systemy mają 3 typy eventów i żyją.

0

No ale u mnie to są 3 akcje usera:

  1. zmiana imienia
    2, zmiana zdjęcia
  2. wyczyszczenie imienia i zdjęcia

Czy w takim razie to nie jest antypattern, że jednak zrobię 1 event i wepchne tam wszystkie informacje z profilu (nie tylko imię i zdjęcie ale też jakiś nickname, wiek i 5 innych pół) ?

1

Tu poniekąd decyduje biznes - czy chcesz mieć w historii kilka niezależnych wpisów:

  • 1523 - zmieniono imię
  • 1547 - zmieniono zdjęcie
  • 1567 - zmieniono pięć innych pól (ładowanie zdjęcia trochę trwało, więc i minuta była dłuższa niż zwykle)

Czy też starczy:

  • 1551 - zmieniono profil

Event może mieć pola opdjonalne - wtedy poniekąd masz jeden event, ale z podtypami.
Ważnym elementem decyzyjnym jest fakt, że eventy nie dają się łatwo zmieniać i migrować.

Na mojego czuja - jeśli Twoja aplikacja robi też coś innego niż wymiany zdjęć i imion (to nie Tinder) - to raczej walnij jeden event - uprość sobie życie.
Ale jeśli to Tinder i te zmiany, to podstawa biznesu to wiele eventów może mieć sens (ale nie musi).

0

Generalnie eventy powinny mieć pewną "ziarnistość". Na przykład nie ma sensu generować eventu ZipCodeChanged lub StreetChanged, wystarczy po prostu dać AddressChanged. Zazwyczaj biznes interesuje to że adres uległ zmianie a nie że zmienił się kod pocztowy.

W twoim przypadku jeżeli zmiana imienia/czy avataru niewiele biznes obchodzi to spokojnie można to wrzucić w UserProfileUpdated i po sprawie. Z drugiej strony taka np. zmiana preferencji marketingowych już powinna iść osobnym eventem.

1

Jeśli masz trzy oddzielne akcje, gdzie np. za każdym razem użytkownik potwierdza i wysyłany jest request do API, dochodzi do zmiany encji, zapisania, zwrot do użytkownika i później kolejna akcja to faktycznie wtedy należałoby to rozbić. Najlepiej zazwyczaj kierować się prostą zasadą, że payload eventu powinien zawierać zmiany stanu aplikacji. Czyli np. jeśli w jednej operacji zmieniliśmy mail, imię i datę urodzenia użytkownika, to payload będzie zawierał właśnie te informacje. Jeśli zmieniliśmy tylko email, to payload zawiera tylko email.

Swoją drogą to ogarnijcie trochę ludzie te kategorie. To nie jest pytanie z działu Java. To że używasz akurat w swojej aplikacji Javy nie ma nic do tematu. Takie wątki się nagminnie powtarzają. Ich miejsce jest w dziale inżyniera oprogramowania.

1

Z dokładnością do tego, że event nie powinien być 1-1 z wewnętrznym modelem, np. encją, ponieważ wówczas ograniczamy możliwości zmian tego modelu bez zepsucia klientów.

Do tego eventy typu UserChanged mają tendencję puchnąć w nieskończoność - wszystko tam można wsadzić, a potem domenowo za jakość tych danych odpowiada producent, który za Chiny nie wie co oznacza pole X.

Ja bym generował eventy mniejszej ziarnistości, oczywiście podszedł do tematu pragmatycznie. Czasem warto dodać jakieś informacje do eventu, aby np. uniknąć wyścigu na późniejszych etapach procesu.

1

@Charles_Ray: ja to widzę tak, event musi zawsze być przypisany do jakiegoś spójnego obiektu. W przypadku adresu zmieniany jest cały value-object adres w encji. W przypadku profilu zakładam że np. encja/agregat user ma value-object profilePreferences i to on jest updatowany w całości.

Ale generalnie masz racje, jeżeli to będzie event UserChanged (a więc niespecyficzny) to będzie puchło i co gorsza nie będzie miało za dużej wartości biznesowej (bo nie wiadomo co się zmieniło tak naprawdę i czy to ważne).

1

@Charles_Ray: @0xmarcin prawda, przy czym ja bym dodał że jeśli mamy sytuację gdzie nasza encja User rośnie w nieskończoność (i co za tym idzie odpowiadający mu event) to mamy coś źle zamodelowane, i to tutaj w pierwszej kolejności doszukiwał bym się możliwości poprawy.

0

Wysyłałbym agregat UserProfileUpdated, w środku miał kolekcję z "pod eventami" typu zmieniono zdjęcie. Będziesz przy okazji w stanie ogarnąć atomiczność operacji.

3

Eventy przy Event Sourcingu powinny być jak najbardziej małe. Ale to o co pytasz to EDD, czyli o eventy "latające" pomiędzy mikroserwisami, czyli Event-Carried State Transfer. I tutaj powiem Ci tak:
Jeśli Event lata pomiędzy tym samym mikroserwisem (bo czemu nie) to niech będzie malutki. Przecież dany serwis doskonale zna stan swoich encji czy tam czego (lub agregatów jeśli masz DDD, ale nie musisz mieć). I masz nad tym pełną kontrolę łącznie jeśli robisz refactoring to zmiana jest "lokalna" tj w jednym serwisie. Jeden deploy itp. Dużo problemów z głowy.

Ale jak lata pomiędzy mikroserwisami - to najlepiej niech to będzie duży Event z całym stanem (swoją drogą jeśli masz super mega hiper duże obiekty, to warto to uznać za problem sam w sobie i rozwiązać/przemyśleć). Jeśli dany serwis nie jest zainteresowany całością tylko częścią danych - to OK, bo inny może być zainteresowany inną jego częścią itd. To dużo ułatwia.

Dodam że przy eventach kolejność jest mega ważna (i np dobry event store jak... Event Store rozwiążuje dużo problemów za nas) i tutaj dzięki np timestampom łatwiej sprawę załatwić przy dużych eventach. Jak masz najnowszą wersję stanu który Cię interesuje to jak przychodzi "stary" event po prostu go ignorujesz. Jak masz małe eventy... to musisz pomyśleć o tym która zmiana jest aktualna i dużo bardziej skupić się na tym jeśli występuje konflikt ( i tu znów przy Event sourcingu to kolejny problem do rozwiązania przez dobry store, ale to pytanie o EDD).

1 użytkowników online, w tym zalogowanych: 0, gości: 1