private async Task ManageSnapshotBehavior(
            IDomainEvent @event,
            EventStoreDbContext ctx,
            int hashedAggregateId)
        {
            bool IsSnaphostEnabled()
            {
                return(_snapshotBehaviorProvider != null &&
                       _archiveBehavior != SnapshotEventsArchiveBehavior.Disabled);
            }

            if (@event.AggregateId != null && @event.AggregateType != null)
            {
                var evtType = @event.GetType();
                if (IsSnaphostEnabled())
                {
                    var behavior = _snapshotBehaviorProvider !.GetBehaviorForEventType(evtType);
                    if (behavior?.IsSnapshotNeeded(@event) == true)
                    {
                        var aggState = await GetRehydratedAggregateStateAsync(@event.AggregateId, @event.AggregateType, ctx)
                                       .ConfigureAwait(false);

                        var eventsToArchive = behavior.GenerateSnapshot(aggState);

                        if (eventsToArchive?.Any() == true)
                        {
                            if (aggState != null)
                            {
                                var previousSnapshot = await ctx
                                                       .Set <Snapshot>()
                                                       .FirstOrDefaultAsync(s =>
                                                                            s.HashedAggregateId == hashedAggregateId &&
                                                                            s.AggregateType == @event.AggregateType.AssemblyQualifiedName)
                                                       .ConfigureAwait(false);

                                if (previousSnapshot != null)
                                {
                                    ctx.Remove(previousSnapshot);
                                }
                                ctx.Add(new Snapshot
                                {
                                    AggregateType        = @event.AggregateType.AssemblyQualifiedName,
                                    HashedAggregateId    = hashedAggregateId,
                                    SnapshotBehaviorType = behavior.GetType().AssemblyQualifiedName,
                                    SnapshotTime         = DateTime.Now,
                                    SnapshotData         = aggState.ToJson(new AggregateStateSerialisationContract())
                                });
                            }
                            await StoreArchiveEventsAsync(eventsToArchive, ctx).ConfigureAwait(false);
                        }
                    }
                }
            }
        }
Exemplo n.º 2
0
        private async Task StoreEvent(IDomainEvent @event, EventStoreDbContext ctx, bool useBuffer = true)
        {
            var sequence = Convert.ToInt64(@event.Sequence);

            if (@event.AggregateId != null)
            {
                var hashedAggregateId = @event.AggregateId.ToJson(true).GetHashCode();
                if (sequence == 0)
                {
                    sequence = await ComputeEventSequence(ctx, useBuffer, hashedAggregateId);

                    if (@event is BaseDomainEvent baseDomainEvent)
                    {
                        baseDomainEvent.Sequence = Convert.ToUInt64(sequence);
                    }
                    else
                    {
                        @event.GetType().GetAllProperties()
                        .First(p => p.Name == nameof(IDomainEvent.Sequence)).SetMethod?.Invoke(@event, new object[] { Convert.ToUInt64(sequence) });
                    }
                }
                await ManageSnapshotBehavior(@event, ctx, hashedAggregateId).ConfigureAwait(false);
            }
            var persistableEvent = GetEventFromIDomainEvent(@event, sequence);

            if (_bufferInfo?.UseBuffer == true && useBuffer)
            {
                s_Events.Add(persistableEvent);

                if (!s_BufferEnteredTimeAbsolute.HasValue && !s_BufferEnteredTimeSliding.HasValue)
                {
                    s_BufferEnteredTimeAbsolute = DateTime.Now;
                    s_BufferEnteredTimeSliding  = DateTime.Now;
                    s_AbsoluteTimer.Change(Convert.ToInt32(_bufferInfo.AbsoluteTimeOut.TotalMilliseconds), Timeout.Infinite);
                    s_SlidingTimer.Change(Convert.ToInt32(_bufferInfo.SlidingTimeOut.TotalMilliseconds), Timeout.Infinite);
                }
                else
                {
                    if (DateTime.Now.Subtract(s_BufferEnteredTimeAbsolute ?? DateTime.MaxValue).TotalMilliseconds >= _bufferInfo.AbsoluteTimeOut.TotalMilliseconds)
                    {
                        TreatBufferEvents(null);
                        s_BufferEnteredTimeAbsolute = null;
                        s_BufferEnteredTimeSliding  = null;
                    }
                    else if (DateTime.Now.Subtract(s_BufferEnteredTimeAbsolute ?? DateTime.MaxValue).TotalMilliseconds >= _bufferInfo.SlidingTimeOut.TotalMilliseconds)
                    {
                        TreatBufferEvents(null);
                        s_BufferEnteredTimeAbsolute = null;
                        s_BufferEnteredTimeSliding  = null;
                    }
                    else
                    {
                        s_BufferEnteredTimeSliding = DateTime.Now;
                        s_SlidingTimer.Change(Convert.ToInt32(_bufferInfo.SlidingTimeOut.TotalMilliseconds), Timeout.Infinite);
                    }
                }
            }
            else
            {
                ctx.Add(persistableEvent);
            }
        }