CQRS - Passaggio della radice aggregata come argomento

0

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!

    
posta bojanv55 25.02.2017 - 23:31
fonte

1 risposta

1

Da quanto ho capito provi a implementare un Read model emulandolo usando altro Aggregates o implementando uno snapshot Aggregate usando un altro Aggregate in modo da avere due opzioni:

  1. Sviluppa AlgorithmCachedResult come Read model , cioè una classe che ascolta Phase1Completed e Phase2Completed eventi e li memorizza in un database; tieni presente che questo modello letto può essere alla fine inconsisten o

  2. Implementa una funzione di istantanea all'interno del repository AlgorithmAR , eventualmente utilizzando Decorator pattern , per non rompere il Pattern di responsabilità singola. In questo modo, invece di caricare tutta la cronologia degli eventi, si cerca una versione cache di AlgorithmAR , caricarla se esiste, quindi applicare solo gli eventi che sono stati generati dopo ; potresti generare una nuova versione cache ogni n eventi. Penso che sia quello che vuoi.

risposta data 27.02.2017 - 07:44
fonte