Quindi, ho il seguente codice:
public class CQRSQuestion {
public static void main(String[] args) {
//received command for algorithm run
AlgorithmAR algorithmAR = new AlgorithmAR(111);
algorithmAR.runAlgorithm(1,"2");
//after a while we receive another command to actually save algorithm results
AlgorithmCachedResultAR cachedResultAR = loadCachedAlgResFromRepoById(123);
AlgorithmAR algorithmAR1 = loadAlgorithARFromRepoById(111);
algorithmAR1.applyCache(cachedResultAR);
}
class AlgorithmAR{
int algorithmId;
AlgorithmPhase1Entity1 phase1;
AlgorithmPhase2Entity2 phase2;
void runAlgorithm(int param1, String param2){
phase1.doPhase1(param1, param2);
}
void applyCache(AlgorithmCachedResultAR cachedResultAR){
//since CQRS aggreagates are for writing only, can we use
//something like cachedResultAR.getCache() here?
}
}
class AlgorithmPhase1Entity1{
void doPhase1(int param1, String param2){
//do phase1 and construct Phase1Completed event
Bus.publish(new Phase1Completed());
}
@EventSourcingHandler
void when(Phase1Completed event){
//set state of this object on intial publish and aggregate creation
}
}
class AlgorithmPhase2Entity2{
@EventHandler //event handler is not run at aggregate creation from repo
void when(Phase1Completed event){
//do phase2 and construct Phase2Completed event
Bus.publish(new Phase2Completed());
}
@EventSourcingHandler
void when(Phase2Completed event){
//set state of this object on intial publish and aggregate creation
}
}
class StatelessProcessManagerForAlg{
@ProcessManagerEventHandler
void when(Phase1Completed event){
Bus.publish(new CachePhase1Command());
}
@ProcessManagerEventHandler
void when(Phase2Completed event){
Bus.publish(new CachePhase2Command());
}
}
class AlgorithmCachedResultAR{
int cachedResId;
int algorithmId;
void create(int param1, String param2, String param3){
//init aggreagate after phase 1
Bus.publish(new Phase1Cached());
}
void create(String param3){
//update after phase 2
Bus.publish(new Phase2Cached());
}
@EventSourcingHandler
void when(Phase1Cached event){
//update internal state of this object
}
@EventSourcingHandler
void when(Phase2Cached event){
//update internal state of this object
}
}
}
Qui ho AlgorithmAR
che è radice Aggregate che esegue un algoritmo in 2 fasi.
Dopo aver chiamato runAlgorithm
su di esso, chiama AlgorithmPhase1Entity1
e method doPhase1
. Questa entità quindi come risultato dell'operazione emette l'evento Phase1Completed
. Questo viene pubblicato contemporaneamente alla GUI (async) e al bus eventi per le altre parti interessate.
Qui, l'altra parte interessata è AlgorithmPhase2Entity2
che la riceverà nel gestore di eventi when(Phase1Completed event)
e dopo aver elaborato l'evento emit Phase2Completed
. Inoltre, l'interesse per questo evento è StatelessProcessManagerForAlg
che è saga che emette il comando CachePhase1Command
per la creazione di altro aggregato che memorizza i risultati dell'algoritmo memorizzati nella cache. Questo comando viene instradato al gestore comandi, che come risultato crea AlgorithmCachedResultAR
e chiama il metodo create
su di esso. I param nel metodo create sono estratti dal messaggio CachePhase1Command
.
Tutti i metodi con annotazione @EventSourcingHandler
vengono eseguiti sulla reidratazione dell'aggregato dall'archivio eventi e sull'emitività iniziale degli eventi. Le annotazioni @EventHandler
vengono eseguite solo sull'emit iniziale di eventi.
Ora la domanda - poiché ho bisogno in seguito di applicare i risultati memorizzati nella cache dell'algoritmo da AlgorithmCachedResultAR
all'interno del metodo AlgorithmAR.applyCache(AlgorithmCachedResultAR cachedResultAR)
, dovrei farlo - poiché con CQRS, la radice aggregata è usata solo per scrivere i dati. Qui vorrei effettivamente utilizzare AR per interrogare i dati da esso. Se utilizzo la proiezione di lettura, dovrei creare una copia di 1-1 di AlgorithmCachedResultAR
che sembra ridondante qui. Grazie!