public async Task OnError_Continue_prevents_aggregator_exceptions_from_stopping_catchup() { var count = 0; var projectionStore = new InMemoryProjectionStore <BalanceProjection>(); var projector = new BalanceProjector() .Pipeline(async(projection, batch, next) => { Interlocked.Increment(ref count); if (count < 20) { throw new Exception("oops"); } await next(projection, batch); }).Trace(); var catchup = StreamCatchup.All(streamSource.StreamPerAggregate().Trace(), batchSize: 50); catchup.Subscribe(projector, projectionStore.AsHandler(), onError: e => e.Continue()); await catchup.RunSingleBatch(); projectionStore.Count().Should().Be(31); }
public async Task OnError_Continue_prevents_aggregator_exceptions_from_stopping_catchup() { var projectionStore = new InMemoryProjectionStore <BalanceProjection>(); var count = 0; var projector = new BalanceProjector() .Pipeline(async(projection, batch, next) => { Interlocked.Increment(ref count); Console.WriteLine(count); if (count < 49) { Throw(); } await next(projection, batch); }).Trace(); var catchup = StreamCatchup.Create(stream.Trace(), batchSize: 50); catchup.Subscribe(projector, projectionStore.AsHandler(), onError: e => e.Continue()); await catchup.RunUntilCaughtUp(); projectionStore.Count().Should().Be(1); projectionStore.Single().CursorPosition.Should().Be(1); }
public async Task When_one_projection_fails_its_cursor_is_not_advanced_while_other_projections_cursors_are_advanced() { var projections = new InMemoryProjectionStore <BalanceProjection>(); // first catch up all the projections var stream = streamSource.StreamPerAggregate().Trace(); var catchup = StreamCatchup.All(stream); var initialSubscription = catchup.Subscribe(new BalanceProjector(), projections); await catchup.RunUntilCaughtUp(); initialSubscription.Dispose(); // write some additional events var streamIdsWithoutErrors = streamIds.Take(5).ToList(); var streamIdsWithErrors = streamIds.Skip(5).Take(5).ToList(); foreach (var streamId in streamIdsWithoutErrors.Concat(streamIdsWithErrors)) { store.WriteEvents(streamId, howMany: 10); } // subscribe a flaky projector catchup.Subscribe(new BalanceProjector() .Pipeline(async(projection, batch, next) => { var aggregateId = batch.Select(i => i.AggregateId).First(); if (streamIdsWithErrors.Contains(aggregateId)) { throw new Exception("oops"); } await next(projection, batch); }), projections.AsHandler(), e => e.Continue()); await catchup.RunSingleBatch(); var projectionsWithoutErrors = streamIdsWithoutErrors.Select( id => projections.Get(id).Result); var projectionsWithErrors = streamIdsWithErrors.Select( id => projections.Get(id).Result); foreach (var projection in projectionsWithoutErrors) { projection.CursorPosition.Should().Be(11); projection.Balance.Should().Be(11); } foreach (var projection in projectionsWithErrors) { projection.CursorPosition.Should().Be(1); projection.Balance.Should().Be(1); } }
public async Task When_an_aggregation_fails_then_the_projection_is_not_updated() { var projections = new InMemoryProjectionStore <BalanceProjection>(); var catchup = StreamCatchup.All(streamSource.StreamPerAggregate().Trace()); // subscribe a flaky projector catchup.Subscribe(new BalanceProjector() .Pipeline(async(projection, batch, next) => { bool shouldThrow = true; // declared outside to nudge the compiler into inferring the correct .Pipeline overload if (shouldThrow) { throw new Exception("oops"); } await next(projection, batch); }), projections.AsHandler(), e => e.Continue()); await catchup.RunSingleBatch(); projections.Count().Should().Be(0); }
public async Task When_an_aggregation_fails_then_the_projection_is_not_updated() { var projections = new InMemoryProjectionStore<BalanceProjection>(); var catchup = StreamCatchup.All(streamSource.StreamPerAggregate().Trace()); // subscribe a flaky projector catchup.Subscribe(new BalanceProjector() .Pipeline(async (projection, batch, next) => { bool shouldThrow = true; // declared outside to nudge the compiler into inferring the correct .Pipeline overload if (shouldThrow) { throw new Exception("oops"); } await next(projection, batch); }), projections.AsHandler(), e => e.Continue()); await catchup.RunSingleBatch(); projections.Count().Should().Be(0); }
public async Task OnError_Continue_prevents_aggregator_exceptions_from_stopping_catchup() { var projectionStore = new InMemoryProjectionStore<BalanceProjection>(); var count = 0; var projector = new BalanceProjector() .Pipeline(async (projection, batch, next) => { Interlocked.Increment(ref count); Console.WriteLine(count); if (count < 49) { Throw(); } await next(projection, batch); }).Trace(); var catchup = StreamCatchup.Create(stream.Trace(), batchCount: 50); catchup.Subscribe(projector, projectionStore.AsHandler(), onError: e => e.Continue()); await catchup.RunUntilCaughtUp(); projectionStore.Count().Should().Be(1); projectionStore.Single().CursorPosition.Should().Be(1); }
public async Task OnError_Continue_prevents_aggregator_exceptions_from_stopping_catchup() { var count = 0; var projectionStore = new InMemoryProjectionStore<BalanceProjection>(); var projector = new BalanceProjector() .Pipeline(async (projection, batch, next) => { Interlocked.Increment(ref count); if (count < 20) { throw new Exception("oops"); } await next(projection, batch); }).Trace(); var catchup = StreamCatchup.All(streamSource.StreamPerAggregate().Trace(), batchSize: 50); catchup.Subscribe(projector, projectionStore.AsHandler(), onError: e => e.Continue()); await catchup.RunSingleBatch(); projectionStore.Count().Should().Be(31); }
public async Task When_one_projection_fails_its_cursor_is_not_advanced_while_other_projections_cursors_are_advanced() { var projections = new InMemoryProjectionStore<BalanceProjection>(); // first catch up all the projections var stream = streamSource.StreamPerAggregate().Trace(); var catchup = StreamCatchup.All(stream); var initialSubscription = catchup.Subscribe(new BalanceProjector(), projections); await catchup.RunUntilCaughtUp(); initialSubscription.Dispose(); // write some additional events var streamIdsWithoutErrors = streamIds.Take(5).ToList(); var streamIdsWithErrors = streamIds.Skip(5).Take(5).ToList(); foreach (var streamId in streamIdsWithoutErrors.Concat(streamIdsWithErrors)) { store.WriteEvents(streamId, howMany: 10); } // subscribe a flaky projector catchup.Subscribe(new BalanceProjector() .Pipeline(async (projection, batch, next) => { var aggregateId = batch.Select(i => i.AggregateId).First(); if (streamIdsWithErrors.Contains(aggregateId)) { throw new Exception("oops"); } await next(projection, batch); }), projections.AsHandler(), e => e.Continue()); await catchup.RunSingleBatch(); var projectionsWithoutErrors = streamIdsWithoutErrors.Select( id => projections.Get(id).Result); var projectionsWithErrors = streamIdsWithErrors.Select( id => projections.Get(id).Result); foreach (var projection in projectionsWithoutErrors) { projection.CursorPosition.Should().Be(11); projection.Balance.Should().Be(11); } foreach (var projection in projectionsWithErrors) { projection.CursorPosition.Should().Be(1); projection.Balance.Should().Be(1); } }