public async Task <IEnumerable <object> > QueryEvents(
            Guid streamId, long fromVersion)
        {
            using (EventStoreContext context = _contextFactory.Invoke())
            {
                string stateType = _typeResolver.ResolveTypeName <T>();

                IQueryable <StreamEvent> query =
                    from e in context.StreamEvents
                    where
                    e.StateType == stateType &&
                    e.StreamId == streamId &&
                    e.Version >= fromVersion
                    orderby e.Version ascending
                    select e;

                IEnumerable <object> sequence =
                    from e in await query
                    .AsNoTracking()
                    .ToListAsync()
                    .ConfigureAwait(continueOnCapturedContext: false)
                    let value                       = e.Payload
                                           let type = _typeResolver.TryResolveType(e.EventType)
                                                      select _jsonProcessor.FromJson(value, type);

                return(sequence.ToImmutableArray());
            }
        }
 public async Task PublishEvents(string stateType, Guid streamId)
 {
     using (EventStoreContext context = _contextFactory.Invoke())
     {
         await FlushEvents(context, stateType, streamId).ConfigureAwait(continueOnCapturedContext: false);
     }
 }
Пример #3
0
 public async Task ScanPendingEvents()
 {
     using (EventStoreContext context = _contextFactory.Invoke())
     {
         await ScanPendingEvents(context).ConfigureAwait(continueOnCapturedContext : false);
     }
 }
Пример #4
0
        public static async Task ClassInitialize(TestContext context)
        {
            _connection = new SqliteConnection("DataSource=:memory:");
            await _connection.OpenAsync();

            _options     = new DbContextOptionsBuilder().UseSqlite(_connection).Options;
            using var db = new EventStoreContext(_options);
            await db.Database.EnsureCreatedAsync();
        }
Пример #5
0
        private Task ScanPendingEvents(EventStoreContext context)
        {
            var query = from e in context.PendingEvents
                        where DateTime.UtcNow - e.RaisedTimeUtc >= _minimumPendingTime
                        group e by new { e.StateType, e.StreamId } into s
            select s.Key;

            return(query.ForEach(t => SendFlushCommand(t.StateType, t.StreamId)));
        }
Пример #6
0
 public static IQueryable <PendingEvent> GetPendingEventsQuery(
     this EventStoreContext context,
     string stateType,
     Guid streamId)
 {
     return(from e in context.PendingEvents
            where e.StateType == stateType && e.StreamId == streamId
            orderby e.Version
            select e);
 }
        public async Task TestInitialize()
        {
            Connection = new SqliteConnection("DataSource=:memory:");
            await Connection.OpenAsync();

            DbContextOptions options = new DbContextOptionsBuilder().UseSqlite(Connection).Options;

            ContextFactory = () => new EventStoreContext(options);
            using (EventStoreContext db = ContextFactory.Invoke())
            {
                await db.Database.EnsureCreatedAsync();
            }
        }
Пример #8
0
        private async Task FlushEvents(EventStoreContext context,
                                       string stateType,
                                       Guid streamId)
        {
            IQueryable <PendingEvent> query         = context.GetPendingEventsQuery(stateType, streamId);
            List <PendingEvent>       pendingEvents = await query.ToListAsync().ConfigureAwait(continueOnCapturedContext: false);

            foreach (IEnumerable <PendingEvent> window in Window(pendingEvents))
            {
                string partitionKey = $"{streamId}";
                await _eventBus.Send(window.Select(GenerateMessage), partitionKey).ConfigureAwait(continueOnCapturedContext: false);

                context.PendingEvents.RemoveRange(window);
                await context.SaveChangesAsync().ConfigureAwait(continueOnCapturedContext: false);
            }
        }
        private async Task SaveAndPublish(string stateType,
                                          Guid transaction,
                                          Guid streamId,
                                          long startVersion,
                                          ImmutableArray <object> events,
                                          TracingProperties tracingProperties = default)
        {
            await SaveEvents().ConfigureAwait(continueOnCapturedContext: false);
            await PublishPendingEvents().ConfigureAwait(continueOnCapturedContext: false);

            async Task SaveEvents()
            {
                using (EventStoreContext context = _contextFactory.Invoke())
                {
                    for (int i = 0; i < events.Length; i++)
                    {
                        object source = events[i];

                        var streamEvent = new StreamEvent(
                            stateType,
                            streamId,
                            version: startVersion + i,
                            raisedTimeUtc: DateTime.UtcNow,
                            eventType: _typeResolver.ResolveTypeName(source.GetType()),
                            payload: _jsonProcessor.ToJson(source),
                            messageId: $"{Guid.NewGuid()}",
                            tracingProperties.OperationId,
                            tracingProperties.Contributor,
                            tracingProperties.ParentId,
                            transaction);

                        context.Add(streamEvent);
                        context.Add(new PendingEvent(streamEvent));
                    }

                    await context.SaveChangesAsync().ConfigureAwait(continueOnCapturedContext: false);
                }
            }

            Task PublishPendingEvents() => _publisher.PublishEvents(stateType, streamId);
        }
Пример #10
0
        private async Task SaveAndPublish(string stateType,
                                          Guid transaction,
                                          Guid streamId,
                                          long startVersion,
                                          ImmutableArray <object> events,
                                          TracingProperties tracingProperties = default)
        {
            await SaveEvents().ConfigureAwait(continueOnCapturedContext: false);
            await PublishPendingEvents().ConfigureAwait(continueOnCapturedContext: false);

            async Task SaveEvents()
            {
                using EventStoreContext context = _contextFactory.Invoke();

                for (int i = 0; i < events.Length; i++)
                {
                    object source = events[i];

                    var streamEvent = new StreamEvent(
                        stateType,
                        streamId,
                        version: startVersion + i,
                        raisedTimeUtc: DateTime.UtcNow,
                        eventType: _typeResolver.ResolveTypeName(source.GetType()),
                        payload: _jsonProcessor.ToJson(source),
                        messageId: $"{Guid.NewGuid()}",
                        tracingProperties.OperationId,
                        tracingProperties.Contributor,
                        tracingProperties.ParentId,
                        transaction);

                    context.Add(streamEvent);
                    context.Add(PendingEvent.Create(streamEvent));
                }

                List <UniqueProperty> uniqueProperties = await context
                                                         .Set <UniqueProperty>()
                                                         .Where(p => p.StateType == stateType && p.StreamId == streamId)
                                                         .AsNoTracking()
                                                         .ToListAsync()
                                                         .ConfigureAwait(continueOnCapturedContext: false);

                foreach ((string name, string value) in GetUniqueProperties(events))
                {
                    UniqueProperty property = uniqueProperties.Find(p => p.Name == name);

                    if (value == null)
                    {
                        if (property != null)
                        {
                            context.UniqueProperties.Remove(property);
                        }
                    }
                    else
                    {
                        if (property == null)
                        {
                            context.Add(new UniqueProperty(stateType, streamId, name, value));
                        }
                        else
                        {
                            property.SetValue(value);
                            context.Update(property);
                        }
                    }
                }

                await context.SaveChangesAsync().ConfigureAwait(continueOnCapturedContext: false);
            }

            Task PublishPendingEvents() => _publisher.PublishEvents(stateType, streamId);
        }