Ejemplo n.º 1
0
        AggregateRoot PrepareFromSnapshot <TAggregateRoot>(Snapshot matchingSnapshot, long maxGlobalSequenceNumber, IUnitOfWork unitOfWork, string aggregateRootId)
        {
            var instance             = matchingSnapshot.Instance;
            var hadEventsAppliedToIt = false;
            var stopwatch            = Stopwatch.StartNew();

            if (matchingSnapshot.ValidFromGlobalSequenceNumber < maxGlobalSequenceNumber)
            {
                var info = new AggregateRootInfo(instance);

                foreach (var e in _eventStore.Load(aggregateRootId, info.SequenceNumber + 1))
                {
                    if (e.GetGlobalSequenceNumber() > maxGlobalSequenceNumber)
                    {
                        break;
                    }
                    var domainEvent = _domainEventSerializer.Deserialize(e);
                    info.Apply(domainEvent, unitOfWork);
                    hadEventsAppliedToIt = true;
                }

                info.SetUnitOfWork(unitOfWork);
            }

            if (hadEventsAppliedToIt && stopwatch.Elapsed > _preparationThreshold)
            {
                _snapshotStore.SaveSnapshot <TAggregateRoot>(aggregateRootId, instance, maxGlobalSequenceNumber);
            }

            return(instance);
        }
            public void MaybeApply(DomainEvent domainEvent, RealUnitOfWork realUnitOfWork, long requestedGlobalSequenceNumber)
            {
                // other roots' events are not relevant
                if (domainEvent.GetAggregateRootId() != _aggregateRootInfo.Id)
                {
                    return;
                }

                var globalSequenceNumberFromEvent = domainEvent.GetGlobalSequenceNumber();

                // don't do anything if we are not supposed to go this far
                if (globalSequenceNumberFromEvent > requestedGlobalSequenceNumber)
                {
                    return;
                }

                // don't do anything if the event is in the past
                if (globalSequenceNumberFromEvent <= _globalSequenceNumber)
                {
                    return;
                }

                // if this entry is a future version of the requested version, it's not ok.... sorry!
                if (_globalSequenceNumber > requestedGlobalSequenceNumber)
                {
                    IsOk = false;
                    return;
                }

                try
                {
                    var sequenceNumberFromEvent    = domainEvent.GetSequenceNumber();
                    var expectedNextSequenceNumber = _aggregateRootInfo.SequenceNumber + 1;

                    if (expectedNextSequenceNumber != sequenceNumberFromEvent)
                    {
                        IsOk = false;
                        return;
                    }

                    _aggregateRootInfo.Apply(domainEvent, realUnitOfWork);

                    _globalSequenceNumber = globalSequenceNumberFromEvent;
                }
                catch (Exception exception)
                {
                    _logger.Warn(exception, "Got an error while bringing cache entry for {0} up-to-date to {1}",
                                 _aggregateRootInfo.Id, requestedGlobalSequenceNumber);

                    IsOk = false;
                }
            }