/// <summary> /// StartConsumers - start consumers and connect them to a queue. /// </summary> /// <param name="consumerName">Consumer name</param> /// <param name="retryQueueDetails">Retry queue details if a message needs to be requeued with a delay (a Dead letter exchange must be defined)</param> /// <param name="queueName">Queue where the consumers will connect (optional - if not defined, the config value is used)</param> /// <param name="totalConsumers">Total consumers to start (optional - if not defined, the config value is used)</param> /// <param name="createQueue">Create queue to connect when starting consumers (optional - default is false)</param> /// <exception cref="RabbitMQClientException"></exception> public void StartConsumers(string consumerName, RetryQueueDetails retryQueueDetails, string queueName = null, byte?totalConsumers = null, bool createQueue = false) { var config = (IBrokerConfigConsumers)_config; var totalConsumersToStart = totalConsumers ?? config.TotalInstances; if (totalConsumersToStart <= 0) { throw new ArgumentException("Invalid total number of consumers to start"); } var triedCreateQueue = false; for (var i = 0; i < totalConsumersToStart; i++) { var routingKeyOrQueueName = string.IsNullOrWhiteSpace(queueName) ? config.RoutingKeyOrQueueName : queueName; var totalCreatedConsumers = _consumers.Count; var connection = GetConnection(ServiceDescription + "_" + i, totalCreatedConsumers, MaxChannelsPerConnection); var channel = connection.CreateModel(); if (createQueue && !triedCreateQueue) { try { RabbitMqUtilities.CreateQueueOrGetInfo(routingKeyOrQueueName, channel); triedCreateQueue = true; } catch (Exception e) { throw new RabbitMqClientException($"Unable do create queue. Details: {e.Message}", e); } } var consumer = new AsyncEventingBasicConsumerExtended(channel) { ConnectedToPort = connection.Endpoint.Port, ConnectedToHost = connection.Endpoint.HostName, ConnectionTime = DateTime.Now, Id = i, RetentionPeriodInRetryQueueMilliseconds = retryQueueDetails?.RetentionPeriodInRetryQueueMilliseconds ?? 0, RetentionPeriodInRetryQueueMillisecondsMax = retryQueueDetails?.RetentionPeriodInRetryQueueMillisecondsMax ?? 0, RetryQueue = retryQueueDetails?.RetryQueue }; consumer.Received += Consumer_Received; consumer.Shutdown += Consumer_Shutdown; var tag = $"{consumerName}_{i}"; consumer.ConsumerTag = tag; _consumers.Add(consumer); channel.BasicConsume(routingKeyOrQueueName, false, tag, consumer); } }
private void RequeueMessageWithDelay(AsyncEventingBasicConsumerExtended consumer, BasicDeliverEventArgs deliveryArgs, string messageAdditionalInfo) { if (string.IsNullOrWhiteSpace(consumer.RetryQueue)) { return; } var properties = consumer.Model.CreateBasicProperties(); RabbitMqUtilities.SetPropertiesSenderRequeueMessageWithDelay(properties, consumer.RetentionPeriodInRetryQueueMilliseconds, consumer.RetentionPeriodInRetryQueueMillisecondsMax); var firstErrorTimeStamp = RabbitMqUtilities.GetFirstErrorTimeStampFromMessageArgs(deliveryArgs.BasicProperties); SetFirstErrorTimeStampToProperties(firstErrorTimeStamp, properties); SetMessageAdditionalInfoToProperties(messageAdditionalInfo, properties); consumer.Model.BasicPublish( "", consumer.RetryQueue, properties, deliveryArgs.Body); }