Sto cercando alcune informazioni su come gestire il modello di lettura in un'applicazione CQRS Event Sourcing, al fine di fare il meglio per garantire la coerenza dei dati.
Il punto mancante è come essere sicuri (in realtà non è sicuro, ma ragionevolmente sicuro) che le proiezioni all'interno del modello di lettura siano in grado di elaborare gli eventi creati dal modello di scrittura nell'ordine previsto (che è l'ordine in cui il modello di scrittura ha generato gli eventi) .
Proviamo a chiarire lo scenario con un esempio.
Supponiamo di avere un'app con uno stack di scrittura che genera eventi per un aggregato chiamato news e leggere stack fatto da una singola proiezione, che è fondamentalmente una tabella denormalizzata che elenca tutte le notizie con alcune proprietà ( ad esempio il titolo, il riassunto e il nome dell'autore).
In questo modo, un'app client è in grado di visualizzare un'interfaccia utente che elenca tutte le ultime notizie pubblicate dagli editori.
L'infrastruttura per il sourcing di eventi è un archivio eventi che salva gli eventi come documenti all'interno di una raccolta MongoDB e quindi pubblica un messaggio corrispondente su un bus di servizio, in modo che con un classico modello pub-sub tutte le proiezioni interessate sono in grado di sottoscrivere il messaggio e fare il lavoro adeguato in risposta ad esso.
Per coloro che hanno familiarità con RabbitMQ , questo tipo di cose potrebbe essere implementato utilizzando uno
In questo tipo di scenario, il modello di scrittura e il modello di lettura vengono distribuiti su macchine diverse che possono essere ridimensionate indipendentemente l'una dall'altra, in base al carico della richiesta sia sullo stack di scrittura che sullo stack di lettura.
Dato questo scenario, è del tutto possibile che in un dato momento ci siano due o più istanze dell'app che ospita il modello di lettura del nostro sistema . Queste istanze saranno consumatori concorrenti sugli eventi pubblicati dal modello di scrittura.
Immagina ora che in un breve intervallo di tempo due eventi, ad esempio E1 ed E2, siano pubblicati sul bus di servizio e che ci siano due istanze in esecuzione, ad esempio M1 e M2, dell'app che ospita il modello letto.
Dato questo scenario è del tutto possibile che l'evento E1 venga elaborato dalla macchina M1 e che l'evento E2 sia elaborato contemporaneamente dalla macchina M2 (ricorda che le due istanze sono concorrenti sui messaggi pubblicati a il bus di servizio). A questo punto lo stato finale della proiezione è imprevedibile , perché ognuna delle istanze potrebbe essere più veloce dell'altra.
Un esempio tipico è quando entrambi gli eventi sono di tipo TitleSet , perché un editore ha deciso di cambiare il titolo delle notizie due volte in un intervallo di tempo molto breve: al termine dell'elaborazione la proiezione contiene il titolo sbagliato per le notizie e il titolo errato sarà visibile agli utenti finali nell'applicazione client (che, ovviamente, ottiene i dati per l'interfaccia utente dalla proiezione).
Qual è il modo migliore per gestire questo tipo di scenario in modo da garantire la massima coerenza possibile nello stack di lettura dell'applicazione?
P.S .: gli eventi E1 ed E2 sono stati generati nell'ordine atteso dal modello di scrittura e sono stati memorizzati correttamente all'interno dell'Event Store. L'incoerenza dei dati di cui stiamo parlando riguarda solo il modello di lettura .