Gestione della coerenza finale durante la persistenza e la pubblicazione di eventi

0

Attualmente sto lavorando su un'applicazione DDD che utilizza il sourcing di eventi con redis come archivio principale di persistenza. Quindi, sfortunatamente non ho dei rollback incorporati in caso di problemi. L'applicazione è un monolite con 3 radici aggregate separate

Il seguente metodo di servizio

  1. Crea il mio aggregrate "Trip"
  2. Richiamare il repository del negozio per mantenere tutti gli eventi associati alla creazione dell'aggregato.
  3. Richiama il repository dell'istantanea per creare un'istantanea di aggregazione persistente
  4. Pubblica eventi per aggiornare altri aggregati nel monolite (mantenere un accoppiamento lento)

Sto usando c # ma la lingua è irrilevante qui:

public async Task<bool> CreateTripAsync(CreateTripRequest request)
{
    //Factory method to create Trip aggregate
    var trip = Trip.Create(request);

    //Persist trip events
    await _tripEventRepository.SaveEventsAsync(trip.Events);

    //Persist trip snapshot
    try
    {
        await _tripSnapshotRepository.SaveAsync(liveTrip);
    }
    catch
    {
        //Deal with eventual consistency by replaying stored events?? How do we trigger this to happen
    }

    //Publish all events associated with creating trip (e.g. 'PassengerAddedEvent') which will affect other aggregates in the same service
    // Mediators publish is fire and forget 
    var tasks = trip.Events.Select(async (ev) => { await _mediator.Publish(ev); });
    await Task.WhenAll(tasks);

    return true;
}

Le mie domande sono:

  1. Il mio servizio sta facendo le 4 cose di cui sopra. Tutti loro sono associati alla creazione di un viaggio. Questo violerebbe SRP per questo metodo? Io non la penso così perché sembrano tutti avere lo stesso livello di astrazione.
  2. Se la memorizzazione dei miei eventi nell'archivio eventi ha esito positivo, ma improvvisamente lì è un'interruzione dell'infrastruttura e non riesco ad aggiornare la mia istantanea, come posso gestire questa incoerenza? Stavo pensando di pianificare un'attività in background che riproduce gli eventi associati a questo viaggio per ricreare l'aggregato e quando ritorna online lo mantiene. Tuttavia, supponiamo che superi il mio set un numero massimo di tentativi?

  3. Dato che sto lavorando in un monolite, sto utilizzando il MediatR pacchetto nuget che è un incendio e dimentico di un pub sub spedizione / gestore dell'evento. Dovrebbe esserci un errore nella pubblicazione di uno di questi gestori di eventi, avrò i miei aggregati in stati incoerenti. So che la maggior parte dei bus di servizio a livello aziendale hanno code di messaggi che vengono automaticamente riprovate / archiviate dopo le eccezioni. Tuttavia non riesco a trovare nulla sull'integrazione di un ESB in un monolite e forse un ESB sarebbe eccessivo nel mio caso ??

posta Josh L 20.08.2018 - 19:18
fonte

1 risposta

0

Would this violate SRP for this method?

Non abbastanza per cui valga la pena preoccuparsi. Potresti ragionevolmente chiedere se il codice questo ha davvero bisogno di capire che "salva" significa "aggiorna tre diversi negozi", o se è qualcosa che dovrebbe essere astratto dietro un'altra funzione. Ad esempio, è probabile che molti diversi comportamenti di Trip richiedano un salvataggio, se tutti hanno una propria copia del protocollo di salvataggio o devono condividere un protocollo comune.

Hai le tue preoccupazioni per il dominio separate dai tuoi dubbi sulla persistenza, che è la cosa più importante.

If storing my events in the event store succeeds but suddenly their is an infrastructure outage and I can not update my snapshot, how can I deal with this inconsistency.

Sii più esplicito su tempo / orologio e come rendere resiliente il consumatore dello snapshot. Ad esempio, se l'istantanea viene salvata con metadati che descrivono la posizione in cui è stato eseguito lo stream dell'evento, è possibile ripristinare l'istantanea in seguito utilizzando solo i nuovi eventi.

Se la cronologia che sto guardando ha 100 eventi e l'istantanea che ho è stata creata dall'evento 95, è facile aggiornare l'istantanea con i nuovi eventi. Quindi non è un grosso problema se il tentativo di aggiornare lo snapshot fallisce.

Questo è essenzialmente lo stesso modo in cui funziona un log write-ahead-log del database.

Should there be an error in publishing one of these event handlers, I will have my aggregates in inconsistent states.

Puoi ripubblicare gli eventi in seguito, specialmente se progetti i tuoi aggregati in modo che riconoscano i messaggi che hanno già visto (ovvero: gestione evento idempotente). Vale a dire, è possibile organizzare sia la pubblicazione degli eventi quando le modifiche aggregate e anche su una pianificazione. Questo ti dà almeno una volta la consegna , devi solo ottenere l'aggregato per gestire i duplicati.

Vedi anche Nessuno ha bisogno di messaggi affidabili .

    
risposta data 20.08.2018 - 20:03
fonte