private async Task <List <IEventMessageDraft> > CreateEventMessagesAsync(IEventSourcedAggregateRoot aggregate, IReadOnlyCollection <DomainAggregateEvent> events) { var messages = new List <IEventMessageDraft>(); Guid?aggregateClassId = entityTypeManager.TryGetClassInfoByClrType(aggregate.GetType())?.Id; if (aggregateClassId == null) { throw new InvalidOperationException($"Cannot save event sourced aggregate of type {aggregate.GetType()}: its class ID has not been defined"); } foreach (DomainAggregateEvent ev in events) { IEventMessageDraft message = await eventMessageFactory.CreateMessageAsync(ev); message.SetMetadata(BasicEventMetadataNames.AggregateClassId, aggregateClassId.Value.ToString()); message.SetMetadata(BasicEventMetadataNames.AggregateVersion, (aggregate.Version + 1).ToString()); if (aggregate is ITenantOwned tenantOwned) { message.SetMetadata(BasicEventMetadataNames.AggregateTenantId, tenantOwned.TenantId?.ToString()); } messages.Add(message); } return(messages); }
public void Set(IEventSourcedAggregateRoot aggregateRoot) { if (aggregateRoot == null) { return; } var aggregateRootId = aggregateRoot.Id; var aggregateRootType = aggregateRoot.GetType(); var cacheKey = GetCacheKey(aggregateRootId, aggregateRootType); if (_logger.IsEnabled(LogLevel.Debug)) { _logger.LogDebug($"Setting aggregate root to memory cache[LRU], Id: {aggregateRootId}, Type: {aggregateRootType}."); } _cache.Add(cacheKey, aggregateRoot); }
public async Task CheckpointAsync( IEventSourcedAggregateRoot aggregateRoot, CancellationToken token = default) { var aggregateRootId = aggregateRoot.Id; var aggregateRootType = aggregateRoot.GetType().FullName; var aggregateGeneration = aggregateRoot.Generation; var aggregateVersion = aggregateRoot.Version; var metrics = await _eventStateBackend.StatMetricsAsync(aggregateRootId, aggregateGeneration, token); if (metrics.TriggerCheckpoint(_options)) { var nextGeneration = ++aggregateRoot.Generation; var checkpoint = new AggregateRootCheckpoint <IEventSourcedAggregateRoot>(aggregateRoot.Id, aggregateRoot.GetType(), nextGeneration, aggregateRoot.Version, aggregateRoot); var message = $"id: {aggregateRootId}, Type: {aggregateRootType}, Generation: {nextGeneration}, Version: {aggregateVersion}, UnCheckpointedBytes: {metrics.UnCheckpointedBytes} >= {_options.UnCheckpointedBytes}, UnCheckpointedCount: {metrics.UnCheckpointedCount} >= {_options.UnCheckpointedCount}"; try { await _checkpointStateBackend.AppendAsync(checkpoint, token); } catch (Exception e) { _logger.LogInformation($"Checkpointing the aggregate root, {message} has a unknown exception: {LogFormatter.PrintException(e)}."); return; } _logger.LogInformation($"Checkpointed the aggregate root, {message}."); } else { _logger.LogInformation($"No triggering checkpoint for the aggregate root, id: {aggregateRootId}, Type: {aggregateRootType}, Generation: {aggregateGeneration}, Version: {aggregateVersion}, UnCheckpointedBytes: {metrics.UnCheckpointedBytes} < {_options.UnCheckpointedBytes}, UnCheckpointedCount: {metrics.UnCheckpointedCount} < {_options.UnCheckpointedCount}."); } }