Jak wdrożyć menedżera procesów w pozyskiwaniu zdarzeń


14

Pracuję nad małą przykładową aplikacją do nauki pojęć CQRS i pozyskiwania zdarzeń. Mam Basketagregat i Productagregat, który powinien działać niezależnie.

Oto pseudo kod pokazujący implementację

Basket { BasketId; OrderLines; Address; }

// basket events
BasketCreated { BasketId; }
ItemAdded { BasketId; ProductId; Quantity }
AddItemSucceeded { BasketId; ProductId; Quantity }
AddItemRevoked { BasketId; ProductId; Quantity }
ItemRemoved { BasketId; ProductId; Quantity }
CheckedOut { BasketId; Address }

Product { ProductId; Name; Price; }

// product events
ProductReserved { ProductId; Quantity }
ProductReservationFailed { ProductId; Quantity }
ProductReservationCancelled { ProductId; Quantity; }

Polecenia są bardzo podobne do zdarzeń, używają nazwy rozkazującej, a nie czasu przeszłego.

W tej chwili działają one samodzielnie niezależnie. Wydaję polecenie AddItem, a ono tworzy ItemAddedzdarzenie w Basketagregacie, które robi to, co musi zrobić ze stanem „Koszyka”. Podobnie w przypadku produktu polecenia i zdarzenia działają dobrze.

Chciałbym teraz połączyć to w proces, który przebiegałby mniej więcej tak (pod względem poleceń i zdarzeń, które się zdarzają):

Kierownik procesu wykonałby następujące czynności:

on BasketCreated: CreateShoppingProcess
on ItemAdded: ReserveProduct
on ProductReserved: SucceedAddingItem // does nothing, but needs to be there so that the basket knows it can check out
on ProductReservationFailed: RevokeAddItem
on RemoveItem: CancelProductReservation
on Checkout: CreateOrder // create an order and so on...

Pytania, na które nie mogłem znaleźć ostatecznych odpowiedzi, to:

  1. Czy muszę utrwalać menedżera procesów? Wygląda na to, że tak, ale nie jestem pewien
  2. Jeśli tak, muszę zapisać zdarzenia dla menedżera procesów. Jednak zdarzenia, których słucha, są powiązane z agregacjami. Czy dodam do nich identyfikator procesu? Czy mam osobne zdarzenia tylko dla menedżera procesu? Jak to zrobić i zachować jak największą SUSZENIE
  3. Skąd mam wiedzieć, dla którego koszyka ProductReservedsą wydarzenia? Czy to jest w porządku mieć BasketIdje też, czy to przeciekające informacje?
  4. Jak zachować związek między wydarzeniami, skąd mam wiedzieć, które ItemAddedwydało które ProductReservedwydarzenie? Czy przekazuję EventId? To wydaje się dziwne ...
  5. Czy powinienem implementować Basketjako menedżer procesów zamiast zwykłego agregatu?

Po kilku dalszych badaniach doszedłem do tego: Saga jest czymś, co utrzymuje własne wydarzenia i słucha wydarzeń z zewnątrz. Zasadniczo jest to agregat, który może również reagować na zdarzenia zachodzące poza jego własnym małym światem.

Menedżer procesów współpracuje ze zdarzeniami z zewnątrz i wysyła polecenia. Jego historię można odbudować na podstawie zdarzeń, które miały miejsce w agregatach, które mają wspólny identyfikator, taki jak korelacja.


Wygląda na to, że próbujesz zakodować w swoim systemie formalny proces, który parafrazuje istniejący nieformalny przypadek użycia złożony z szeregu poleceń. Robiąc to, wygląda na to, że oprócz istniejących już tworzysz wiele zbędnych poleceń i zdarzeń. Czy to twoja intencja? Czego potrzebuje firma, aby sformalizować rzeczy jako proces w kodzie? Co w Twojej domenie wymaga zidentyfikowania tego procesu i jego uzasadnienia jako pełnej koncepcji?
guillaume31,

Jest to całkowicie złożony projekt, którego celem jest nauczenie się, jak sprawić, by dwa względnie niezależne agregaty współpracowały ze sobą. Więc tak naprawdę nie ma prawdziwej „potrzeby biznesowej”, a ja staram się w miarę możliwości unikać nadmiarowości w tych poleceniach i zdarzeniach. Stąd zamieszanie z menedżerem procesu., Ponieważ wydaje się, że nie powinno się powtarzać rzeczy, które agregaty już obsługują. Jednak muszę jakoś zachować połączenie między tymi dwoma agregatami. Wydaje się, że użycie związku przyczynowego i korelacji może pomóc, ale muszę to wypróbować.
Ivan Pintar,

Odpowiedzi:


14

Przeczytaj, co napisał Rinat Abdullin na temat ewoluującego procesu biznesowego . W szczególności zwróć uwagę na jego zalecenie dotyczące opracowania procesu biznesowego w szybko zmieniającym się środowisku - kierownik procesu jest „tylko” zautomatyzowanym zamiennikiem człowieka wpatrującego się w ekran.

Mój własny model mentalny menedżera procesów polega na tym, że jest to projekcja pochodząca od zdarzenia, w której można wyszukać listę oczekujących poleceń.

Czy muszę utrwalać menedżera procesów? Wygląda na to, że tak, ale nie jestem pewien

To model do czytania. Menedżera procesów można odbudować z historii zdarzeń za każdym razem, gdy jest to potrzebne; lub możesz potraktować to jak aktualizowaną migawkę.

Jeśli tak, muszę zapisać zdarzenia dla menedżera procesów.

Nie - kierownik procesu jest menedżerem . Sam w sobie nie robi nic pożytecznego; zamiast tego nakazuje agregatom wykonanie pracy (tj. dokonanie zmian w księdze rekordów).

Skąd mam wiedzieć, dla którego koszyka przeznaczone są zdarzenia ProductReserved? Czy to w porządku, aby mieć na nich także BasketId, czy to przeciekające informacje

Pewnie. Uwaga: w większości „prawdziwych” domen zakupowych nie nalegasz na rezerwowanie zapasów przed przetworzeniem zamówienia; dodaje niepotrzebnej rywalizacji do firmy. Bardziej prawdopodobne jest, że Twoja firma będzie chciała przyjąć zamówienie, a następnie przeprasza w rzadkim przypadku, że zamówienie nie może zostać zrealizowane w wymaganym czasie.

Jak zachować relację między zdarzeniami, skąd mam wiedzieć, który produkt ItemAdded wyprodukował które zdarzenie ProductReserved?

Wiadomości zawierają metadane - w szczególności można dołączyć identyfikator przyczynowości (aby można było określić, które polecenia wywołały które zdarzenia) i identyfikator korelacji , aby ogólnie śledzić konwersację.

Na przykład menedżer procesów zapisuje własny identyfikator jako korelację w poleceniu; zdarzenia wygenerowane przez skopiowanie identyfikatora korelacji polecenia, a menedżer procesu subskrybuje wszystkie zdarzenia, które mają własną korelację.

Czy powinienem wdrożyć koszyk jako menedżera procesów zamiast zwykłego agregatu?

Moja rekomendacja to nie. Ale Udi Dahan ma inną opinię, którą powinieneś przeanalizować; to znaczy, że CQRS ma sens tylko wtedy, gdy twoje agregaty są sagami - Udi użył sagi w miejscu, w którym kierownik procesu stał się dominującą pisownią.

czy menedżerowie procesów powinni pobierać agregaty?

Nie całkiem? Menedżerowie procesów zajmują się głównie aranżacją, a nie stanem domeny. Instancja procesu będzie miała „stan” w postaci historii wszystkich zaobserwowanych zdarzeń - właściwa czynność w odpowiedzi na zdarzenie Z zależy od tego, czy widzieliśmy zdarzenia X i Y Może więc być konieczne przechowywanie i ładowanie reprezentacji tego stanu (może to być coś płaskiego lub historia obserwowanych zdarzeń).

(Mówię „nie bardzo”, ponieważ agregacja jest zdefiniowana na tyle niejasno, że nie jest całkowicie błędem twierdzenie, że lista zaobserwowanych zdarzeń jest „agregacją”. Różnice są bardziej semantyczne niż implementacja - ładujemy stan procesu, a następnie decydujemy, do jakich komunikatów wyślij do części systemu odpowiedzialnych za stan domeny . Trwa tutaj machanie ręką).

Czyli PM nie musi używać jednego rodzaju zarządzania stanem nad innym, ponieważ jest odpowiedzialny tylko za robienie rzeczy na żywo, a nigdy podczas powtórek?

Niezupełnie - zarządzanie stanem nie jest do zrobienia, to narzędzie do śledzenia opiekunów. W okolicznościach, gdy menedżer procesów nie powinien emitować żadnych sygnałów, dajesz mu obojętne połączenia ze światem. Innymi słowy, dispatch(command)jest to brak op.


1
Mówisz: Możesz przebudować menedżera procesów z historii zdarzeń za każdym razem, gdy go potrzebujesz ... Ale aby go odbudować, muszę zapisać dla niego zdarzenia. A może powinienem go odbudowywać na podstawie zdarzeń w agregacjach? Część, z którą się zmagam to: w przypadku agregatów zdarzenia mają identyfikator agregacji i łatwo je odbudować, znajdując wszystkie zdarzenia o tym identyfikatorze agregacji. Ale jak mam to zrobić dla kierownika procesu? Czy powinienem to robić dla kierownika procesu? A może kierownik procesu powinien wyszukiwać agregaty, gdy musi zdecydować coś na podstawie zdarzenia, które się pojawiło?
Ivan Pintar,

Brakowało mi pojęcia związku przyczynowego i korelacji w pozyskiwaniu zdarzeń. Kiedy się na to spojrzyłem, twoja odpowiedź na czwarte pytanie wreszcie miała sens.
Ivan Pintar,

1
Chciałbym odpowiedzieć na pierwszy komentarz @IvanPintar; czy menedżerowie procesów powinni pobierać agregaty? Czy powinni budować własne w oparciu o przetwarzane przez siebie zdarzenia? W takim przypadku procedury obsługi zdarzeń musiałyby być wolne od skutków ubocznych, prawda?
Jeff

@Jeff W jednym przykładzie, który zrobiłem, menedżer procesów miał własną pamięć, która była aktualizowana przy każdym przetworzonym zdarzeniu, rodzaj modelu odczytu. Było to łatwe do zrobienia i łatwe do śledzenia, co zostało już przetworzone. W innym przykładzie menedżer procesów utworzył i zapisał własne zdarzenia, zbudowane ze zdarzeń agregujących. Podobnie jak powyżej, ale stan był pozyskiwany ze zdarzeń. W zależności od złożoności stanu utrzymywanego przez menedżera procesów łatwiejsze może być wykonanie jednego lub drugiego. Pierwsze podejście było dla mnie prostsze.
Ivan Pintar

Ciekawe, więc mniej więcej to zależy od programisty, o ile menedżer procesu reaguje na zdarzenia i ostatecznie wydaje polecenia?
Jeff

2

To, czego szukasz, ma wzorzec zwany „Saga”, który jest w zasadzie menedżerem procesów.

Sagi są również idealne do długotrwałych procesów, ponieważ mogą utrzymywać stan między skorelowanymi poleceniami.

Oto świetny artykuł na temat Sagas

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.