15 komentářů k článku Architektura našeho systému: Angular, Event sourcing a CQRS:

  1. Taco

    Předgenerování ID.
    ad generování ID: Proč tak přísně bazírovat na tom, že commad nevrací hodnotu? Stejně to není pravda – vrací status zda byl či nebyl úspěšný. Když můžu dodatečně revertovat provedení akce, může stejně dobře updatovat hodnotu ID. IMHO.

    1. tomkisw

      Re: Předgenerování ID.
      Command vrací pouze status zdali byl úspěšně přijat (HTTP 202 vs 5xx) , to nic neříká o úspěšnosti jeho zpracování, které je navíc asynchronní.

      1. Rasta

        Re: Předgenerování ID.
        IMHO spracovanie nemusi byt nutne asynchronne, resp. nie vsetky spracovania musia byt synchronne/asynchronne. Tento pristup si si zvolil ty. Ale ako som uz pisal inde, mozno som len nepochopil tie clanky na webe ohladom CQRS :)

    2. tomkisw

      Re: Předgenerování ID.
      Command je pouze žádost, neví vůbec nic o tom jaké Eventy ve skutečnosti budou emitovány, tj. i nově vytvořené entity/aggregate ID. Command ID !== Entity/Aggregate ID. Je zřejmě, že pokud Command vrátí 5xx tak nikdy nebude zpracován, na druhou stranu pokud vrátí 202 tak to ještě automaticky nemusí znamenat jeho úspěšné provedení.

  2. Rasta

    Nacitanie entity
    Ohladom tohto:

    Před samotným zpracováním Commandu proto tzv. instancujeme entitu kampaně, na které se Command provádí. To znamená, že z Monga vytáhneme všechny Události, které se týkají dané kampaně, a aplikujeme je na danou entitu.

    Si si isty, ze to je spravny pristup? Mozno pre ten marketingovy system je to ok, ale ak by kazda entita mala ulozenych tisicky eventov, tak by tento pristup nebol pouzitelny. Nie je lepsie udrziavat aktualny ‚snapshot‘ v nejakej relacnej DB? Mam pocit ze vsade to robia tak, ale mozno som aj nieco zle pochopil :) V takom pripade nacitanei entity znamena nacitanie jedneho riadku v DB.

    1. Lukáš HavrlantAutor příspěvku

      Re: Nacitanie entity
      Samozřejmě si nejsem jistý, zda je to správný přístup! Ale zatím je to přístup, který nám stačí. Je nám jasné, že časem stačit nebude, i my máme máme entity, které žijí dlouho (Customer) a časem tak i pro ně nevyhnutelně budou tisíce Událostí. Až to bude problém, tak to budeme řešit a nejspíš přidáme nějakou cache přímo tam, kde se ty entity instancují. Tzn., že když dnes instancuju Customera, uložím si jeho stav do paměti a když ho budu instancovat zítra, donačtu jen Události, které pro ni vznikly ode dneška. Ale je to jen pracovní neodzkoušený nápad.

      1. Dominik Geršák

        Re: Nacitanie entity
        Skôr by som to riešil tak, aby vždy ste mali nejaký záznam s aktuálnym snapshotom, kľudne aj v databáze. Proste sa vyberie tento dokument. Všetky tie eventy si samozrejme bokom ukladať a vytvoriť si logiku, ktorá ten snapshot vie kedykoľvek aktualizovať. Toto by ste si vedeli spúšťať kľudne aj na pozadí, alebo keď sa udeje nejaký event, ktorý tie data výraznejšie zmení a je proste nevyhnutné ten snapshot updatnúť.

        Takto by sa využívali naplno všetky prednosti Vášho prístupu – stav aktuálnej entity odvodený od postupnej aplikácie všetkých modifikácii a zároveň aj jendoduchý prístup k aktuálnym dátam skrz jediný prístup k DB (za ideálneho stavu, že ten výsledný dokument obsahuje všetky hodnoty a už žiadne referencie).

        Sám som raz podobný princíp použil (u mňa šlo len o sled +/- nejakého čísla, nič zložité) a bol som s tým mimoriadne spokojný.

        1. Lukáš HavrlantAutor příspěvku

          Re: Nacitanie entity
          Tyhle snapschoty tam máme (viz kapitola Queries a View Buildery), ale nepoužíváme je, když jde o něco tak důležitého, jako je instancování entit při zpracování commandů, tedy když vytváříme nové Události. Má to totiž několik nevýhod:

          • Update snapshotu trvá dlouho a během té doby by nešly zpracovávat commandy, protože bychom neměli k dispozici správná data.
          • Existuje prodleva mezi tím, kdy se Událost dostane do Event Store a kdy se dostane do snapshotu ― takže když někdo smaže Kampaň, tak tato Událost už může být v Event Store, ale nemusí být aplikovaná v snapshotu, takže by se mohlo stát, že necháme projít command na smazané Kampani jednoduše proto, že o tom výmazu ještě vlastně nevíme.
          • Vytváříme tím závislost na další databázi ― teď nám stačí jen Event Store, při zpracování commandů z něj čteme a do něj zapisujeme a nikam dál nehrabeme.

          Když vždy poctivě načteme a aplikujeme všechny Události, tak zmíněné problémy nemáme. Snapshoty/View máme pro Queries, které mohou vracet data, která už nejsou v daném čase platná, tam nám to nevadí.

  3. Honza Široký

    Concurrency
    Jak resite concurrency problemy? Co se napriklad stane, kdyz dva uzivatele budou editovat stejnou kampan a oba ve stejnou chvili odeslou commandy, prvni na pozastaveni kampane a druhy na smazani kampane. Predpokladejme, ze z pohledu business logiky by nemelo byt mozne pozastavit smazanou kampan. Jak ve vasi architekture resite to, aby se do event storu nedostal nejdrive „delete“ command a pak „pause“ command? Tedy aby v event storu nebyla kampan v nekonzistentnim stavu.

    1. Lukáš HavrlantAutor příspěvku

      Re: Concurrency
      Na začátku zpracování commandu si zjistíme, v jaké revizi je daná entita, to je nějaké číslo. Takže oba commandy by si třeba zjistili, že Kampaň má revizi 41. Do Event Store by se pak oba commandy snažily uložit Kampaň pod revizi 42 a to už se tomu druhému v pořadí nepodaří. Ten druhý command by se pak začal zpracovávat znova a už by věděl o tom předchozím commandu/eventu.

  4. Radek Ježdík

    Důvod
    Můžu se zeptat, co bylo důvodem pro použití CQRS a ES? Znám několik důvodů, proč to používat, ale v této aplikaci mi to nějak nesedí. Pokud jsem to pochopil, tak jde o víceméně CRUD systém s ne zrovna multi-user collaborative environmentem. Jaký byl problém, který jste tím chtěli řešit a jestli jste si spíš nepřidělali práci?

  5. saxicek

    CouchDB
    Znáš CouchDB? Proč jste nepoužili ji? Řeší stejné problémy a navíc přesně tak, jak popisuješ. Data ukládá jako event stream, kolize řeší přes version, má podporu view přes map/reduce. Navíc byste měli zdarma PouchDB pro mobilní užití. Zdá se mi, že takhle jste zbytečně programovali něco, co už je naprogramované.

Napsat komentář

Tato diskuse je již příliš stará, pravděpodobně již vám nikdo neodpoví. Pokud se chcete na něco zeptat, použijte diskusní server Devel.cz

Zdroj: https://www.zdrojak.cz/?p=17106