CQRS query asincrona dal gestore comandi

3

In un contesto di microservizi CQRS / async, ho un gestore di comandi, ad es. SendOrderConfirmationEmailCommandHandler implementato in un servizio di comunicazione.

Dipende dalle informazioni del servizio ordini, che possono essere recuperate tramite GetOrderDetailsQueryHandler.

La sequenza di messaggi per questo processo è:

SendOrderConfirmationEmailCommand - > GetOrderDetailsQuery - > OrderDetailsRetrievedEvent

Poiché tutti i messaggi (inclusa GetOrderDetailsQuery) sono asincroni per necessità, il processo di esecuzione di SendOrderEmailCommandHandler viene chiuso dopo aver inviato un oggetto GetOrderDetailsQuery e quindi in qualche modo deve riprendere da dove era stato interrotto dopo la gestione di OrderDetailsRetrievedEvent.

Quale tipo di schema può essere implementato per risolvere il gap tra l'attivazione di una query e il messaggio di risposta ricevuto in modo tale da essere in grado di conservare e ricollegare all'istanza del messaggio di comando originale per il quale sono stati recuperati i dettagli dell'ordine ?

Può o dovrebbe essere gestito in CommandHandler o altrove?

    
posta yogibear 11.03.2018 - 12:00
fonte

2 risposte

3

È più probabile che tu veda esempi analoghi se cerchi "process manager" o "saga".

Parlando in generale, quello che stai descrivendo è un protocollo, con almeno tre partecipanti; la fonte del comando, il database dei dettagli dell'ordine e il servizio email stesso.

La responsabilità del protocollo è di tenere traccia ; sta facendo la contabilità, cioè sta registrando gli eventi che fanno parte di questa interazione. Qui, gli eventi sarebbero

CommandReceived
OrderDetailsRetrieved
EmailSent

(Scegli l'ortografia migliore se puoi). Quando accade una di queste cose, il manager dei processi lo scrive. Quando è il turno del manager del processo di agire, il gestore esamina gli eventi che ha visto, calcola quali azioni (se presenti) devono essere eseguite successivamente e riporta / esegue tali azioni.

Il rapporto con l'esecuzione è una questione di stile

List<Action> actions = processManager.actions()

Qui, il gestore dei processi ti fornisce una rappresentazione in memoria delle azioni, e il consumatore può decidere come gestirle.

processManager.act(orderDetailsClient, emailClient)

Qui, process manager calcola l'azione da intraprendere e invoca il metodo appropriato sul client appropriato.

Il discorso di Cory Benfield Building Protocol Libraries nel modo giusto è un buon punto di partenza.

    
risposta data 11.03.2018 - 18:37
fonte
1

Devi definire un processo aziendale per inviare l'email. Il processo è come un'entità, ha un ID e uno stato che "ricorda" in quale fase è. Il processo è persistente su una persistenza duratura e viene caricato / salvato dal suo ID.

Ora arriva la parte importante: devi includere l'ID di processo come identificatore di correlazione in tutte le operazioni asincrone che avvia e deve essere presente anche in tutte le risposte . In questo modo, quando è disponibile la risposta asincrona, si utilizza l'ID di correlazione per identificare il processo, caricarlo e si basa sul suo stato corrente, eseguire l'azione successiva o interromperlo se è stato eseguito.

    
risposta data 12.03.2018 - 09:17
fonte