public RabbitMQBatchConsumerWorker(ILogger logger, RabbitMQConnection connection, string queueName, IModel model, IBatchProcessingWorker <T> batchProcessingWorker, IMessageRejectionHandler messageRejectionHandler, ISerializer serializer) { _logger = logger; _model = model; _model.BasicQos(0, batchProcessingWorker.GetBatchSize(), false); _queueName = queueName; _batchProcessingWorker = batchProcessingWorker; _messageRejectionHandler = messageRejectionHandler; _serializer = serializer; CheckAliveFrequency = new TimeSpan(0, 0, 10); }
public async Task DoConsumeAsync(CancellationToken cancellationToken) { //Iterate while thread hasn't been canceled while (!cancellationToken.IsCancellationRequested) { var currentBatchCounter = _batchProcessingWorker.GetBatchSize(); var currentBatch = new List <T>(); BasicGetResult result; ulong lastDeliveryTag = 0; do { result = _model.BasicGet(_queueName, false); if (result != null) { lastDeliveryTag = result.DeliveryTag; currentBatchCounter--; var messageBody = GetBody(result); try { var messageObject = _serializer.Deserialize <T>(messageBody); currentBatch.Add(messageObject); } catch (Exception exception) { var deserializationException = new DeserializationException("Unable to deserialize data.", exception) { SerializedDataString = messageBody, SerializedDataBinary = result.Body, QueueName = _queueName }; await _messageRejectionHandler.OnRejectionAsync(deserializationException).ConfigureAwait(false); //Remove message from queue after RejectionHandler dealt with it _model.BasicNack(result.DeliveryTag, false, false); } } } while (currentBatchCounter > 0 && result != null); if (currentBatch.Count > 0) { var batchFeedbackSender = new RabbitMQBatchFeedbackSender(_model, lastDeliveryTag); try { await _batchProcessingWorker.OnBatchAsync(currentBatch, batchFeedbackSender, cancellationToken).ConfigureAwait(false); if (!batchFeedbackSender.HasAcknoledged) { //Acknoledge message batchFeedbackSender.Ack(); } } catch (Exception e) { //If something went wrong with message processing and message hasn't been acknoledged yet if (!batchFeedbackSender.HasAcknoledged) { //Negatively Acknoledge message, asking for requeue batchFeedbackSender.Nack(true); } //Rethrow caught Exception throw; } } } //Loop ended, dispose ConsumerWorker Dispose(); }