private async Task Subscribe <TContext>(IConnectedProjection <TContext> projection) where TContext : RunnerDbContext <TContext> { if (projection == null || _registeredProjections.IsProjecting(projection.Name)) { return; } long?projectionPosition; using (var context = projection.ContextFactory()) projectionPosition = await context.Value.GetRunnerPositionAsync(projection.Name, CancellationToken.None); if ((projectionPosition ?? -1) >= (_lastProcessedMessagePosition ?? -1)) { _logger.LogInformation( "Subscribing {ProjectionName} at {ProjectionPosition} to AllStream at {StreamPosition}", projection.Name, projectionPosition, _lastProcessedMessagePosition); _handlers.Add( projection.Name, async(message, token) => await projection.ConnectedProjectionMessageHandler.HandleAsync(message, token)); } else { _commandBus.Queue(new StartCatchUp(projection.Name)); } }
public ConnectedProjectionCatchUp( IConnectedProjection <TContext> projection, IConnectedProjectionCatchUpSettings settings, IReadonlyStreamStore streamStore, IConnectedProjectionsCommandBus commandBus, IStreamGapStrategy catchUpStreamGapStrategy, ILogger logger) { _projection = projection ?? throw new ArgumentNullException(nameof(projection)); _settings = settings ?? throw new ArgumentNullException(nameof(settings)); _streamStore = streamStore ?? throw new ArgumentNullException(nameof(streamStore)); _commandBus = commandBus ?? throw new ArgumentNullException(nameof(commandBus)); _catchUpStreamGapStrategy = catchUpStreamGapStrategy ?? throw new ArgumentNullException(nameof(catchUpStreamGapStrategy)); _logger = logger ?? throw new ArgumentNullException(nameof(logger)); }
private void Start <TContext>(IConnectedProjection <TContext>?projection) where TContext : RunnerDbContext <TContext> { if (projection == null || _registeredProjections.IsProjecting(projection.Id)) { return; } _projectionCatchUps.Add(projection.Id, new CancellationTokenSource()); var projectionCatchUp = projection.CreateCatchUp( _streamStore, _commandBus, _catchUpStreamGapStrategy, _logger); TaskRunner.Dispatch(async() => await projectionCatchUp.CatchUpAsync(_projectionCatchUps[projection.Id].Token)); }
private void Start <TContext>(IConnectedProjection <TContext> projection) where TContext : RunnerDbContext <TContext> { if (projection == null || _registeredProjections.IsProjecting(projection.Name)) { return; } _projectionCatchUps.Add(projection.Name, new CancellationTokenSource()); var projectionCatchUp = new ConnectedProjectionCatchUp <TContext>( projection.Name, _streamStore, projection.ContextFactory, projection.ConnectedProjectionMessageHandler, _commandBus, _logger); TaskRunner.Dispatch(async() => await projectionCatchUp.CatchUpAsync(_projectionCatchUps[projection.Name].Token)); }
public When_a_projection_catch_up_processes_a_stream_and_throws_a_detected_stream_gap_exception() { var fixture = new Fixture() .CustomizeConnectedProjectionIdentifiers(); var contextMock = new Mock <IConnectedProjectionContext <FakeProjectionContext> >(); contextMock .Setup(context => context.GetProjectionPosition(It.IsAny <ConnectedProjectionIdentifier>(), It.IsAny <CancellationToken>())) .ReturnsAsync((long?)null); var streamMock = new Mock <IReadonlyStreamStore>(); streamMock .Setup(store => store.ReadAllForwards( It.IsAny <long>(), It.IsAny <int>(), It.IsAny <bool>(), It.IsAny <CancellationToken>())) .ReturnsAsync(() => { var position = fixture.CreatePositive <long>().WithMaximumValueOf(long.MaxValue - 1000); return(new ReadAllPage( position, position.CreateRandomHigherValue(), true, ReadDirection.Forward, (p, token) => throw new NotImplementedException(), fixture.CreateMany <StreamMessage>(2, 10).ToArray())); }); _commandBusMock = new Mock <IConnectedProjectionsCommandBus>(); _gapStrategySettings = fixture.Create <StreamGapStrategyConfigurationSettings>(); var gapStrategyMock = new Mock <IStreamGapStrategy>(); gapStrategyMock .SetupGet(strategy => strategy.Settings) .Returns(_gapStrategySettings); _loggerMock = new FakeLogger(); _projection = new FakeProjection( "catch-up-dummy", (messages, strategy, name, ct) => throw new ConnectedProjectionMessageHandlingException( new StreamGapDetectedException(fixture.CreateMany <long>(1, 10), name), name, new ActiveProcessedStreamState(0)), contextMock.Object); var sut = new ConnectedProjectionCatchUp <FakeProjectionContext>( _projection, ConnectedProjectionSettings.Default, streamMock.Object, _commandBusMock.Object, gapStrategyMock.Object, _loggerMock.AsLogger()); sut.CatchUpAsync(CancellationToken.None).GetAwaiter(); }