Qualche giorno fa in “C come CQRS” abbiamo analizzato, senza scendere troppo nel dettaglio, una possibile implementazione della parte di comandi di CQRS.
Ora, quello che abbiamo ricade a tutti gli effetti sotto il cappello dei tecnicismi, che, sono si importanti, ma senza avere una visione generale del problema trovano il tempo che trovano.
Se ci spostiamo un pelo più in alto e diamo uno sguardo al tutto quello che vediamo, generalizzando molto e prendendo la letteratura alla lettera, è questo:
Ci sono tante implementazioni possibili, anche molto più semplici di quella identificata nel diagramma, ma quello che abbiamo bisogno di capire, prima di tutto, sono i concetti generali e i problemi che certe scelte portano con se; non da meno è importante rendersi conto che all’aumentare delle necessità di scalabilità che abbiamo, o a cui siamo obbligati, è li che tendiamo alla lunga, quindi è li che dobbiamo capire quali sono le insidie che ci si porranno davanti.
Eventualmente consistente
Eventualmente… :-) la prima cosa che appare evidente è che dal momento in cui viene inviata la richiesta di esecuzione di un comando al momento in cui i dati sono leggibili passa inevitabilmente del tempo e, nell’ipotesi molto sensata, che tutti i singoli blocchi siano un processo asincrono il client sa che l’esecuzione del comando è stata “accodata” ma non ha la più pallida idea di quando i dati che quel comando scriverà saranno disponibili per la lettura.
Ci sono tanti modi “tecnologici” per risolvere il problema che abbiamo esposto ma non vogliono essere oggetto di questo post, che mira piuttosto a identificare gli scenari.
Paradigmi
Il primo problema che ci dobbiamo porre è se il problema che abbiamo delineato poco fa sia un vero problema o un presunto problema, il tutto ovviamente calato nel contesto del lavoro che stiamo facendo. L’esperienza fatta sul campo con DDD, CQRS e Event Sourcing, mi fa dire che possiamo generalizzare e ridurre a 3 possibili scenari l’approccio alla scrittura/lettura dei dati (se ne conoscete altri fatevi sotto perché sono molto interessato).
Mi sono permesso di dare dei nomi a questi scenari, non è che mi piacciano molto ma mi aiutano ad identificare meglio quello di cui stiamo parlando.
Front-end/Back-end
è il tipico scenario che abbiamo ad esempio in un CMS, chi scrive non è chi legge, è anche lo scenario più semplice perché il fatto che la consistenza sia “eventuale” è un dettaglio irrilevante, se mi metto dal lato di chi legge dato che non sa nulla di quando è stata scritta l’informazione non ha aspettative e quindi non ha il problema di voler leggere qualcosa che ancora non sa essere scritto.
Put-Get
è il lato opposto della medaglia e anche lo scenario più complesso, un esempio tipico è un qualsiasi work flow in cui ho bisogno del risultato dello passaggio precedente per poter continuare, anche qui generalizzando molto, devo essere in grado di aspettare che i dati siano consistenti per potermi muovere verso il passo successivo.
Per i pignoli: si lo so che c’è Event Sourcing e che il passaggio successivo è dipendente dagli eventi del passaggio precedente e non dai dati ma anche un evento, in quanto per natura asincrono è eventualmente consistente, e quindi mi obbliga in qualche modo ad aspettare.
Side-by-Side
l’ultimo è un mix dei due scenari precedenti in cui un secondo mezzo di comunicazione introduce il problema della consistenza, problema che altrimenti non ci sarebbe: l’utente Mario inserisce nel sistema un nuovo ordine e il suo compito è finito, non ha nessun interesse in quello che succede da li in poi, purtroppo per noi, fa l’inserimento del nuovo ordine mentre è al telefono con Giovanni, il quale invece è molto interessato al nuovo ordine perché gli serve per portare avanti il suo lavoro e dato che Mario gli ha detto che l’ha appena inserito Giovanni comincia a tempestare di F5 il suo browser per il semplice fatto che non vede un ordine che il suo collega gli ha detto di aver creato.
Al prossimo giro: “CQRS: tutti i buoni perché.”
.m