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); } } } } }
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); } }