public async Task <TModel> ProcessAsync <TModel>(String id, Int64 versionUpTo) where TModel : IAtomicReadModel { //Stop condition is version greater than the version we want to apply var readmodel = _atomicReadModelFactory.Create <TModel>(id); var subscription = new AtomicReadModelSubscription <TModel>(_commitEnhancer, readmodel, cs => cs.AggregateVersion > versionUpTo); await _persistence.ReadForwardAsync(id, 0, subscription).ConfigureAwait(false); return(readmodel); }
/// <summary> /// Handle the events. /// </summary> /// <param name="changeset"></param> public async Task <AtomicReadmodelChangesetConsumerReturnValue> Handle( Int64 position, Changeset changeset, IIdentity identity) { if (identity.GetType() != _atomicReadmodelInfoAttribute.AggregateIdType) { return(null); //this is a changeset not directed to this readmodel, changeset of another aggregate. } var rm = await _atomicCollectionWrapper.FindOneByIdAsync(identity.AsString()).ConfigureAwait(false); var readmodelCreated = false; if (rm == null) { //TODO Check if this is the first event. rm = _atomicReadModelFactory.Create <TModel>(identity.AsString()); readmodelCreated = true; } bool readmodelModified; try { readmodelModified = rm.ProcessChangeset(changeset); } catch (Exception ex) { _logger.ErrorFormat(ex, "Error projecting changeset with version {0} with readmodel {1} [{2}] . readmodel will be marked as faulted", changeset.AggregateVersion, AtomicReadmodelInfoAttribute.Name, changeset.Events?.OfType <DomainEvent>()?.FirstOrDefault()?.AggregateId ?? "Unknow aggregate id", ex.Message); rm.MarkAsFaulted(position); readmodelModified = true; //continue. } if (readmodelModified) { if (readmodelCreated) { await _atomicCollectionWrapper.UpsertAsync(rm).ConfigureAwait(false); } else { await _atomicCollectionWrapper.UpdateAsync(rm).ConfigureAwait(false); } return(new AtomicReadmodelChangesetConsumerReturnValue(rm, readmodelCreated)); } return(null); }