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); }
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); }
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" }); }
/// <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); } }