Ejemplo n.º 1
0
        public When_updating_an_active_processed_stream_state_with_a_message()
        {
            var fixture  = new Fixture();
            var position = fixture.Create <long>();

            _sut = new ActiveProcessedStreamState(position);

            _sut.UpdateWithProcessed(fixture.Create <StreamMessage>());
        }
Ejemplo n.º 2
0
        public When_updating_an_active_processed_stream_state_with_a_message_with_the_same_position_as_the_runner()
        {
            var fixture = new Fixture();

            _runnerPosition = fixture.CreatePositive <long>();
            StreamMessage message = fixture
                                    .Build <ConfigurableStreamMessage>()
                                    .WithPosition(_runnerPosition)
                                    .Create();

            _sut = new ActiveProcessedStreamState(_runnerPosition);
            _sut.UpdateWithProcessed(message);
        }
Ejemplo n.º 3
0
        public When_updating_an_active_processed_stream_state_with_a_message_skipping_some_positions()
        {
            var fixture        = new Fixture();
            var runnerPosition = fixture
                                 .CreatePositive <long>()
                                 .WithMaximumValueOf(long.MaxValue - 2);

            _message = fixture
                       .Build <ConfigurableStreamMessage>()
                       .WithPosition(runnerPosition.CreateRandomHigherValue())
                       .Create();

            _sut = new ActiveProcessedStreamState(runnerPosition);
            _sut.UpdateWithProcessed(_message);
        }
Ejemplo n.º 4
0
        public When_updating_an_active_processed_stream_state_with_the_expected_next_message()
        {
            var fixture = new Fixture();

            _runnerPosition = fixture
                              .CreatePositive <long>()
                              .WithMaximumValueOf(long.MaxValue - 1);

            _message = fixture
                       .Build <ConfigurableStreamMessage>()
                       .WithPosition(_runnerPosition + 1)
                       .Create();

            _sut = new ActiveProcessedStreamState(_runnerPosition);
            _sut.UpdateWithProcessed(_message);
        }
Ejemplo n.º 5
0
        public When_updating_an_active_processed_stream_state_with_a_message_with_position_before_the_runner_position()
        {
            var fixture = new Fixture();

            _runnerPosition = fixture
                              .CreatePositive <long>()
                              .WithMinimumValueOf(3);

            _message = fixture
                       .Build <ConfigurableStreamMessage>()
                       .WithPosition(_runnerPosition
                                     .CreateRandomLowerValue()
                                     .WithMinimumValueOf(0))
                       .Create();

            _sut = new ActiveProcessedStreamState(_runnerPosition);
            _sut.UpdateWithProcessed(_message);
        }
        public async Task HandleAsync(
            IEnumerable <StreamMessage> messages,
            IStreamGapStrategy streamGapStrategy,
            CancellationToken cancellationToken)
        {
            ActiveProcessedStreamState?processedState = null;

            using (var context = _contextFactory().Value)
            {
                try
                {
                    var completeMessageInProcess = CancellationToken.None;
                    processedState = new ActiveProcessedStreamState(await context.GetProjectionPosition(Projection, completeMessageInProcess));

                    async Task ProcessMessage(StreamMessage message, CancellationToken ct)
                    {
                        Logger.LogTrace(
                            "[{Projection}] [STREAM {StreamId} AT {Position}] [{Type}] [LATENCY {Latency}]",
                            Projection,
                            message.StreamId,
                            message.Position,
                            message.Type,
                            CalculateNotVeryPreciseLatency(message));

                        await context.ApplyProjections(_projector, message, ct);

                        processedState?.UpdateWithProcessed(message);
                    }

                    foreach (var message in messages)
                    {
                        if (cancellationToken.IsCancellationRequested)
                        {
                            break;
                        }

                        var processAction = DetermineProcessMessageAction(message, processedState);
                        switch (processAction)
                        {
                        case ProcessMessageAction.Skip:
                            continue;

                        case ProcessMessageAction.HandleGap:
                            await streamGapStrategy.HandleMessage(
                                message,
                                processedState,
                                ProcessMessage,
                                Projection,
                                completeMessageInProcess);

                            break;

                        case ProcessMessageAction.Process:
                            await ProcessMessage(message, completeMessageInProcess);

                            break;

                        default:
                            throw new NotImplementedException($"No handle defined for {processAction}");
                        }
                    }

                    if (processedState.HasChanged)
                    {
                        await context.UpdateProjectionPosition(
                            Projection,
                            processedState.Position,
                            completeMessageInProcess);
                    }

                    await context.SaveChangesAsync(completeMessageInProcess);
                }
                catch (TaskCanceledException) { }
                catch (Exception exception)
                {
                    await context.SetErrorMessage(Projection, exception, cancellationToken);

                    throw new ConnectedProjectionMessageHandlingException(exception, Projection, processedState);
                }
            }
        }