Esempio n. 1
0
        public SilverbackIntegrationLoggerBenchmark()
        {
            _integrationLogger = new SilverbackIntegrationLogger(
                new FakeLogger(),
                new LogTemplates().ConfigureAdditionalData <TestConsumerEndpoint>("offset"));

            _singleMessageContext = ConsumerPipelineContextHelper.CreateSubstitute(
                new RawInboundEnvelope(
                    Array.Empty <byte>(),
                    new MessageHeaderCollection
            {
                new MessageHeader("Test", "Test"),
                new MessageHeader(DefaultMessageHeaders.FailedAttempts, 1),
                new MessageHeader(DefaultMessageHeaders.MessageType, "Something.Xy"),
                new MessageHeader(DefaultMessageHeaders.MessageId, "1234"),
            },
                    new TestConsumerEndpoint("Test"),
                    "Test",
                    new TestOffset("abc", "1"),
                    new Dictionary <string, string>
            {
                ["offset"] = "1@42"
            }));

            _sequenceContext = ConsumerPipelineContextHelper.CreateSubstitute(
                new RawInboundEnvelope(
                    Array.Empty <byte>(),
                    new MessageHeaderCollection
            {
                new MessageHeader("Test", "Test"),
                new MessageHeader(DefaultMessageHeaders.FailedAttempts, 1),
                new MessageHeader(DefaultMessageHeaders.MessageType, "Something.Xy"),
                new MessageHeader(DefaultMessageHeaders.MessageId, "5678"),
                new MessageHeader(DefaultMessageHeaders.BatchId, "1234"),
                new MessageHeader(DefaultMessageHeaders.BatchSize, "11"),
            },
                    new TestConsumerEndpoint("Test"),
                    "Test",
                    new TestOffset("abc", "2"),
                    new Dictionary <string, string>
            {
                ["offset"] = "1@43"
            }));
            var sequence = new BatchSequence("123", _sequenceContext);

            sequence.AddAsync(_sequenceContext.Envelope, null, false);
            _sequenceContext.SetSequence(sequence, true);
        }
Esempio n. 2
0
        private async Task <ISequence?> GetSequenceAsync(
            ConsumerPipelineContext context,
            ConsumerBehaviorHandler next,
            ISequenceReader sequenceReader)
        {
            var sequence = await sequenceReader.GetSequenceAsync(context).ConfigureAwait(false);

            if (sequence.IsComplete)
            {
                return(null);
            }

            if (sequence is IncompleteSequence incompleteSequence)
            {
                _logger.LogSkippingIncompleteSequence(incompleteSequence);
                return(null);
            }

            context.SetSequence(sequence, sequence.IsNew);

            if (sequence.IsNew)
            {
                StartActivityIfNeeded(sequence);

                await PublishSequenceAsync(context, next).ConfigureAwait(false);

                if (context.ProcessingTask != null)
                {
                    MonitorProcessingTaskPrematureCompletion(context.ProcessingTask, sequence);
                }

                _logger.LogSequenceStarted(sequence);
            }

            return(sequence);
        }
Esempio n. 3
0
        public SilverbackIntegrationLoggerTests()
        {
            _logger = new LoggerSubstitute <SilverbackIntegrationLoggerTests>();

            _integrationLogger =
                new SilverbackIntegrationLogger <SilverbackIntegrationLoggerTests>(
                    _logger,
                    new LogTemplates()
                    .ConfigureAdditionalData <TestConsumerEndpoint>("offset-in")
                    .ConfigureAdditionalData <TestProducerEndpoint>("offset-out"));

            _singleInboundMessageContext = ConsumerPipelineContextHelper.CreateSubstitute(
                new InboundEnvelope(
                    new MemoryStream(),
                    new MessageHeaderCollection
            {
                new MessageHeader(DefaultMessageHeaders.FailedAttempts, 1),
                new MessageHeader(DefaultMessageHeaders.MessageType, "Something.Xy"),
                new MessageHeader(DefaultMessageHeaders.MessageId, "1234")
            },
                    new TestOffset(),
                    new TestConsumerEndpoint("Test"),
                    "TestActual",
                    new Dictionary <string, string>
            {
                ["offset-in"] = "9"
            }));

            _inboundSequenceContext = ConsumerPipelineContextHelper.CreateSubstitute(
                new InboundEnvelope(
                    new MemoryStream(),
                    new MessageHeaderCollection
            {
                new MessageHeader(DefaultMessageHeaders.FailedAttempts, 1),
                new MessageHeader(DefaultMessageHeaders.MessageType, "Something.Xy"),
                new MessageHeader(DefaultMessageHeaders.MessageId, "1234"),
                new MessageHeader(DefaultMessageHeaders.BatchId, "3"),
                new MessageHeader(DefaultMessageHeaders.BatchSize, "10")
            },
                    new TestOffset(),
                    new TestConsumerEndpoint("Test")
            {
                Batch = new BatchSettings
                {
                    Size = 5
                }
            },
                    "TestActual",
                    new Dictionary <string, string>
            {
                ["offset-in"] = "9"
            }));
            var sequence = new BatchSequence("123", _inboundSequenceContext);

            sequence.AddAsync(_inboundSequenceContext.Envelope, null, false);
            _inboundSequenceContext.SetSequence(sequence, true);

            _outboundEnvelope = new RawOutboundEnvelope(
                new MemoryStream(),
                new MessageHeaderCollection
            {
                new MessageHeader(DefaultMessageHeaders.MessageType, "Something.Xy"),
                new MessageHeader(DefaultMessageHeaders.MessageId, "1234")
            },
                new TestProducerEndpoint("Test"),
                null,
                new Dictionary <string, string>
            {
                ["offset-out"] = "9"
            });
        }
Esempio n. 4
0
        /// <inheritdoc cref="IConsumerBehavior.HandleAsync" />
        public virtual async Task HandleAsync(ConsumerPipelineContext context, ConsumerBehaviorHandler next)
        {
            Check.NotNull(context, nameof(context));
            Check.NotNull(next, nameof(next));

            var sequenceReader = await _sequenceReaders.FirstOrDefaultAsync(reader => reader.CanHandleAsync(context)).ConfigureAwait(false);

            if (sequenceReader == null)
            {
                await next(context).ConfigureAwait(false);

                return;
            }

            // Store the original envelope in case it is replaced in the GetSequence method (see ChunkSequenceReader)
            var originalEnvelope = context.Envelope;

            // Store the previous sequence since it must be added to the new one (e.g. ChunkSequence into BatchSequence)
            var previousSequence = context.Sequence;

            var sequence = await sequenceReader.GetSequenceAsync(context).ConfigureAwait(false);

            if (sequence == null)
            {
                _logger.LogWarningWithMessageInfo(
                    IntegrationEventIds.IncompleteSequenceDiscarded,
                    "The incomplete sequence is ignored (probably missing the first message).",
                    context);

                return;
            }

            context.SetSequence(sequence, sequence.IsNew);

            if (sequence.IsNew)
            {
                await PublishSequenceAsync(context, next).ConfigureAwait(false);

                if (context.ProcessingTask != null)
                {
                    MonitorProcessingTaskPrematureCompletion(context.ProcessingTask, sequence);
                }

                _logger.LogDebugWithMessageInfo(
                    IntegrationEventIds.SequenceStarted,
                    $"Started new {sequence.GetType().Name}.",
                    context);
            }

            await sequence.AddAsync(originalEnvelope, previousSequence).ConfigureAwait(false);

            _logger.LogDebugWithMessageInfo(
                IntegrationEventIds.MessageAddedToSequence,
                $"Message added to {sequence.GetType().Name}.",
                context);

            if (sequence.IsComplete)
            {
                await AwaitOtherBehaviorIfNeededAsync(sequence).ConfigureAwait(false);

                // Mark the envelope as the end of the sequence only if the sequence wasn't swapped (e.g. chunk -> batch)
                if (sequence.Context.Sequence == null || sequence == sequence.Context.Sequence ||
                    sequence.Context.Sequence.IsCompleting || sequence.Context.Sequence.IsComplete)
                {
                    context.SetIsSequenceEnd();
                }

                _logger.LogDebugWithMessageInfo(
                    IntegrationEventIds.SequenceCompleted,
                    $"{sequence.GetType().Name} '{sequence.SequenceId}' completed.",
                    context);
            }
        }