Sto provando a programmare un semplice scenario di acquisto utilizzando il sourcing di eventi:
--------------- --------------- ----------------
| OrderService | | ProductService | | PaymentService |
---------------- ------------------ -----------------
|________________|_____________________|
|
--------------------
| KAFKA |
--------------------
|
--------------------
| PROCESSOR |
--------------------
|
--------------------
| DATABASE |
--------------------
Ci sono 3 servizi:
- Servizio ordini: API che riceve ordini per un prodotto effettuato da un cliente
- Servizio del prodotto: contiene lo stock di prodotti
- Servizio di pagamento: effettua il pagamento dell'ordine
Kafka: archivio eventi per i diversi eventi.
Processore: processore CQRS che genera la visualizzazione dello stato corrente.
Database: visualizzazione materializzata dello stato corrente.
Il mio dubbio principale è come gestire un flusso del genere:
- Il servizio ordini viene chiamato e crea un evento: OrderPlaced
- ProductService verifica la disponibilità di un prodotto e in base a esso crea un evento ProductReserved o OrderCancelledNoStock.
- PaymentService ha elaborato il pagamento in caso di evento ProductReserved, producendo un nuovo evento: OrderCompleted.
Poiché si tratta di un puro approccio di sourcing degli eventi, ProductService non ha un database.
- È una buona pratica considerare la vista materializzata nel DATABASE come la fonte della verità del sistema riguardante lo stock? Secondo me l'unica fonte di verità dovrebbe essere gli eventi, non dovrebbe?
- Vedo molto probabilmente trovare incongruenze dovute alle latenze nel processo CQRS DATABASE, ecco perché l'utilizzo del database come sorgente di thruth è davvero rischioso. Tuttavia avere una visione materializzata sembra essere l'unico modo per conoscere lo stock attuale dei prodotti e del processo o non un ordine di prodotto.
Casi problematici che mi vengono in mente:
- Due OrderPlaced simultanei per lo stesso prodotto arrivano a ProductService. Questo chiama il DATABASE per verificare se c'è disponibilità del prodotto (1 prodotto rimasto). Dato che va bene, entrambi creano un evento ProductReserved per lo stesso prodotto e PaymenService lo elaborerà.
- Un ordine OrderPlaced arriva a ProductService. 1 prodotto rimasto quindi pubblica ProductReserved. Arriva un altro ordine per lo stesso prodotto prima che il DATABASE venga aggiornato dal processo CQRS. Quindi pubblica un altro prodotto conservato nonostante non abbia abbastanza scorte.
Qual è il modo consigliato di gestire uno scenario come questo?