Come implementare un gestore di processo nel sourcing di eventi

11

Sto lavorando su una piccola applicazione di esempio per apprendere i concetti di CQRS e di gestione degli eventi. Ho un aggregato Basket e un aggregato Product che dovrebbe funzionare in modo indipendente.

Ecco qualche pseudo codice per mostrare l'implementazione

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; }

I comandi sono abbastanza simili agli eventi, usando il nome imperativo e non il passato.

In questo momento questi funzionano bene indipendentemente. Rilascio un comando AddItem e crea un evento ItemAdded sull'aggregato Basket che fa ciò che deve fare con lo stato del 'Cestino'. Allo stesso modo, per il prodotto il comando e gli eventi funzionano bene.

Mi piacerebbe ora combinare questo in un processo che farebbe qualcosa di simile (in termini di comandi ed eventi che accadono):

Il gestore del processo dovrebbe eseguire le seguenti operazioni:

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...

Le domande a cui non sono riuscito a trovare risposte definitive sono:

  1. Devo mantenere il gestore dei processi? Sembra come me, ma non sono sicuro
  2. Se lo faccio, ho bisogno di salvare gli eventi per il gestore dei processi. Tuttavia, gli eventi che sta ascoltando sono legati agli aggregati. Devo aggiungere l'id del processo a quelli? Ho eventi separati solo per il responsabile del processo? Come fare questo e mantenere il più ASCIUTTO possibile
  3. Come faccio a sapere a che cosa servono gli eventi ProductReserved ? Va bene avere un BasketId anche su quelli, o sono informazioni che perdono?
  4. Come faccio a mantenere una relazione tra gli eventi, come faccio a sapere quale ItemAdded ha prodotto quale evento ProductReserved ? Passo un EventId ? Questo sembra strano ...
  5. Devo implementare Basket come gestore dei processi invece di un semplice aggregato?

Dopo un po 'di ricerca sono arrivato a questo: Una Saga è qualcosa che mantiene i suoi eventi e ascolta gli eventi dall'esterno. Fondamentalmente, è un aggregato che può anche reagire agli eventi che accadono al di fuori del proprio piccolo mondo.

Un Process Manager funziona con gli eventi dall'esterno e invia i comandi. La cronologia può essere ricostruita dagli eventi che si sono verificati sugli Aggregati che condividono un identificatore comune come un ID di correlazione.

    
posta Ivan Pintar 05.10.2016 - 23:19
fonte

2 risposte

10

Esamina ciò che ha scritto Rinat Abdullin su evoluzione del processo aziendale . In particolare, si noti la sua raccomandazione per lo sviluppo di un processo aziendale in un ambiente in rapida evoluzione - un manager di processo è "solo" una sostituzione automatica per un essere umano che fissa uno schermo.

Il mio modello mentale di un gestore di processi è che si tratta di una proiezione basata su eventi che puoi richiedere per un elenco di comandi in attesa.

Do I need to persist the process manager? It seems like I do, but I'm not sure

È un modello letto. Puoi ricostruire il gestore dei processi dalla cronologia degli eventi ogni volta che ne hai bisogno; oppure puoi trattarlo come un'istantanea che aggiorni.

If I do, I need to save the events for the process manager.

No - il gestore dei processi è un gestore . Non fa nulla di utile da solo; invece dice agli aggregati di fare il lavoro (cioè, apportare modifiche al libro del record).

How do I know what basket the ProductReserved events are for? Is it OK to have a BasketId on those too, or is that leaking info

Certo. Nota: nella maggior parte dei domini commerciali "reali", non vorrai insistere per prenotare l'inventario prima di elaborare un ordine; aggiunge contesa inutile al business. È più probabile che la tua azienda desideri accettare l'ordine, quindi scusa nel raro caso in cui l'ordine non possa essere evaso nel tempo richiesto.

How do I keep a relationship between events, how do I know which ItemAdded produced which ProductReserved event?

I messaggi hanno metadati - in particolare, puoi includere un causationIdentifier (in modo da poter identificare quali comandi hanno prodotto quali eventi) e un correlationIdentifier , per tracciare generalmente la conversazione.

Ad esempio, il gestore processi scrive il proprio id come correlationId nel comando; gli eventi generati da una copia l'id di correlazione del comando e il gestore dei processi si iscrive a tutti gli eventi che hanno il proprio parametro di correlazione.

Should I implement the Basket as a process manager instead of a simple aggregate?

La mia raccomandazione è no. Ma Udi Dahan ha un'opinione diversa che dovresti rivedere; che è CQRS ha senso solo se i tuoi aggregati sono sagas - Udi saga usata nel luogo in cui il responsabile processi è diventato l'ortografia dominante.

should process managers retrieve aggregates?

Non proprio? I gestori di processo sono principalmente interessati all'orchestrazione, non allo stato del dominio. Un'istanza di un processo avrà uno "stato", sotto forma di una cronologia di tutti gli eventi che hanno osservato: la cosa corretta da fare in risposta all'evento Z dipende dal fatto che abbiamo visto o meno eventi X e Y Quindi potrebbe essere necessario essere in grado di memorizzare e caricare una rappresentazione di quello stato (che potrebbe essere qualcosa di piatto, o potrebbe essere la cronologia degli eventi osservati).

(Dico "non proprio" perché aggregato è definito vagamente che non è completamente sbagliato affermare che l'elenco di eventi osservati è un "aggregato". sono più semantici dell'implementazione - carichiamo stato del processo e poi decidiamo quali messaggi inviare alle parti del sistema responsabili di stato del dominio . C'è un po 'di mano che saluta qui.)

So the PM does not need to use one type of state management over another because it is only responsible for doing stuff live and never during replays?

Non proprio - la gestione dello stato non è un do-er, è un tracker di custode di-er. Nelle circostanze in cui il gestore del processo non deve emettere alcun segnale, gli dai connessioni inerte al mondo. In altre parole, dispatch(command) è un non-operatorio.

    
risposta data 06.10.2016 - 00:39
fonte
1

Quello che stai cercando ha un pattern chiamato "Saga", che è essenzialmente un gestore di processi.

I Saga sono perfetti anche per i processi a lungo termine, perché possono mantenere lo stato tra i comandi correlati.

Ecco un grande articolo su Sagas

    
risposta data 09.10.2016 - 01:33
fonte

Leggi altre domande sui tag