Command Pattern, czy jest jakas alternatywa?

0

Nie wiedziałem jak nazwać do końca temat. Więc jak ktoś wpadnie na lepszy pomysł to prosiłbym o propozycje

Założenie:
Mam do zrobienia następującą rzecz.

  1. Pobrac dane
  2. Przetworzyc je
    3.1) Wyslać na maila
    3.2) Wysłać do zewnetrznego systemu
    3.3) Zweryfikowac dane z zewnetrznym systemem

wszystkie podpunkty zawierające 3 mogą być uruchomione jak chcą (nawet nie musi być w ogole 3 wykonywany)

Co potrzebuje
Gdy któryś z skonfigurowanej ścieżki (planu) zawiedzie chcę

  1. automatycznie ponowic próbę X razy
  2. jeżeli po X razach nie udało się to przechodzi w stan zły i trzeba ten konkretny plan poprawić ręcznie (np email był niepoprawny i chciałbym go zmienić)
  3. Ręcznie odpalić dany plan (ale nie cały, tylko od tego stanu gdzie się zatrzymał)

Co wymyśliłem
Command Pattern z "Steps". Czyli https://www.dofactory.com/net/command-design-pattern Invoker bedzie dodawal odpowiednie command (zapewne dodam jakiegos buildera, ktory mi przygotuje invokera)
Jeżeli kod uruchamia dany command, to taki status (parametry) zapisuje w bazie (by pozniej moc je pobrac i zmodyfikowac gdy bedzie wymagana reczna edycja)
Sam command będzie wiedział czy wykonał się dobrze czy nie. Zapisuje ten status (w bazie)
Gdzieś z zewnatrz robie view do tabeli z "planami" i wyswietlam wszystkie te które nie posiadaja że każdy command został wykonany poprawnie
W Bazie tworze status dla calego planu. Pomysł jaki mam to mieć tabele z tymi stepsami + planId. PlanId będzie miał jakies FK która ścieżka (plan) byłą wkorzystana.
Jeżeli chodzi o uruchamianie commandu to mam WebJoba i wrzuce do niego na Queue dany step i on jakoś się tam uruchomi.

To rozwiązanie wydaje mi się skomplikowane i szukam lepszego

1

Jak rozumiem GUI tu nie będzie?
O ile nie potrzebuje raportów typu: ile razy w ciągu ostatniego tygodnia operacja przetworzenia danych wywaliła się pomiedzy 3 a 5 razy, to odpuszczam sobie zapisywanie stanu w SQL.
Robię to prevaylerem - który też jest zrobiony na command pattern, jednak w twoim systemie ważne by było aby jednych i drugich nie powieszać.

Podobne rzeczy ogarniam przy pomocy 2 odległych mechanizmów - na grubo - tam gdzie użytkownicy (biznes) musi faktycznie przerywać i zmieniać flow -> BPMN activity. Ale dla aprzypadku jak u Ciebie to byłby overkill jak z Koluszek do Honolulu.
Na lekko to takie flowy mam w Reactive Streamach (Spring reactor ostatnio, wcześniej RxJava). Tak są operatory typu retry itp. Wada: stan flowu będzie w czystym ram, bez perzystowania. Restartu aplikacji raczej nie przeżyje :-). Przyznam, że pewnie mając coś takiego jak u Ciebie wybrałbym opcję ze streamami i spróbował, powiedziałbym tylko - chłopaki... weźcie restartujcie tego (ha ha ha). Jakkolwiek nie wszystko pasuje. Streamy raczej nie nadają się do sytuacji gdzie decyzja zalezy od kroku ludzkiego (choć na siłe się da).

1

Może rozbić to na 2 serwisy -> jeden (lub więcej) emituje zdarzenia na jakąś kolejkę a drugi (potencjalnie zwielokrotniony) zdejmuje z kolejki i odpala. Kolejka (jakiś SQS na przykład) zalatwia problem restartów, eventy sie nie gubią, możesz robić retry dopóki nie zdejmiesz elementu z kolejki. Można też emitować takie cos ręcznie jeśli jest taka potrzeba. Masz wtedy rozwiazanie enterprise ready :P

0

@Shalom: czyli mam podobny pomysl

Jeżeli chodzi o uruchamianie commandu to mam WebJoba i wrzuce do niego na Queue dany step i on jakoś się tam uruchomi.
webjob to wlasnie SQS ale wlasnie juz z serwisem polaczone (czyli ten drugi serwis co zdejmuje z kolejki).
Teraz Serwis ktory emituje zdarzenie by odbierał jakis generyczny IPlanCommand (kolekcja commandow), obrabial go (zapisywal stan commandu i przez to ze bedzie mozliwosc odpalenia tego z GUI zrobilbym zapisalbym to w bazie @jarekr000000) i wysylal.
Nastepnie ten serwis przetwarza wynik od webjoba. Zmienia status w bazie czy sie udalo czy nie.

Teraz pytanie, jak zrobisz jakis fajny model SQLowy dla wszystkich command? Bo teraz mam tylko 5 commandow wiec moge zrobic 5 kolumn i dac do tego RequestId i sobie sprawdzac co poszlo tak lub nie. Ale jak przyjdzie mi kolejne 10 commandow... to bedzie troszke takie srednie

moze jeszcze inaczej napisze pytanie
Jak fajnie (i latwo) przechowywac czy plan (czyli kilka commandow) sie wykonywal?

@jarekr000000 nie moge nic znalezc na temat BPMB activity podeslalbys jakiegos linka?

1

nie moge nic znalezc na temat BPMB activity podeslalbys jakiegos linka?

BPMN ;) A Activiti to jest silnik do odpalania takich przepływów. Ale to mocny overkill tutaj.

Nie prościej mieć jakąś tabele słownikową (a z punktu widzenia kodu to jakis Enum pewnie) z tymi możliwymi akcjami i potem w innej tabeli mieć powiazania id_joba, typ_akcji, rezultat? ;)

0

nie slyszalem tego terminu, wiec chcialbym sobie poczytac :)

wierze, ze jest to overkill bo problem jest w miare prosty

W Bazie tworze status dla calego planu. Pomysł jaki mam to mieć tabele z tymi stepsami + planId. PlanId będzie miał jakies FK która ścieżka (plan) byłą wkorzystana

Nie prościej mieć jakąś tabele słownikową (a z punktu widzenia kodu to jakis Enum pewnie) z tymi możliwymi akcjami i potem w innej tabeli mieć powiazania id_joba, typ_akcji, rezultat

chyba (nie jestem pewien) jest to ten sam pomysl :) I mam problem z jego napisaniem ze strony bazy danych

Plan {
int id;
int result;
FK PlanScheme
}

PlanScheme {
// normalnie dalbym tutaj List<ICommandNames>, ale nie wiem w sumie jak to ladnie zrobic ze strony bazy danych
}
1

Nie no ja bym prędzej widział:

Plan{
  id
}

Step{
  id
}

PlanSteps{
  planId
  stepId
  result
}

Ewentualnie cos wiecej można wrzucic do PlanSteps jak potrzebujesz.

0

jeszcze pytanie. Co sadzicie, zeby w steps dodac CommandName i na podstawie Name automatycznie tworzyc command jezeli jest potrzebny, z danymi parametrami

0

Piszesz o stanach... Aż sama pcha się maszyna stanów. Chociaż nie wiem, czy to nie za dużo jak dla tych wymagań. Komendy mogą opierać się na maszynie stanów.

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