예제 #1
0
        public MessageProcessor(
            TimeSpan defaultRetryTimeout,
            ICompositeFormatterResolver formatterResolver,
            IInternalMessageQueue internalQueue,
            ILogFactory logFactory,
            Func <string, IMessagePublisher> repliesPublisher,
            IRejectManager rejectManager,
            IRetryManager retryManager,
            IServiceProvider serviceProvider,
            IMessageSubscriptionsRegistry subscriptionsRegistry) : base(logFactory)
        {
            _defaultRetryTimeout = defaultRetryTimeout;
            _formatterResolver   = formatterResolver;
            _internalQueue       = internalQueue;
            _log                   = logFactory.CreateLog(this);
            _logFactory            = logFactory;
            _repliesPublisher      = repliesPublisher;
            _rejectManager         = rejectManager;
            _retryManager          = retryManager;
            _serviceProvider       = serviceProvider;
            _subscriptionsRegistry = subscriptionsRegistry;

            _id = Interlocked.Increment(ref _instanceCounter);
        }
예제 #2
0
        public static MessageSubscriber Create(IServiceProvider serviceProvider,
                                               IMessageSubscriptionsRegistry subscriptionsRegistry,
                                               IConnection connection,
                                               ILogFactory logFactory,
                                               ICompositeFormatterResolver formatterResolver,
                                               Func <string, IMessagePublisher> repliesPublisher,
                                               string exchangeName,
                                               string queueName,
                                               TimeSpan defaultFirstLevelRetryTimeout,
                                               TimeSpan maxFirstLevelRetryMessageAge,
                                               int maxFirstLevelRetryCount,
                                               int firstLevelRetryQueueCapacity,
                                               int processingQueueCapacity,
                                               int messageConsumersCount,
                                               int messageProcessorsCount)
        {
            var log = logFactory.CreateLog(typeof(MessageSubscriber));

            log.Info("Creating RabbitMq subscriber...", new
            {
                exchangeName,
                queueName,
                defaultFirstLevelRetryTimeout,
                maxFirstLevelRetryMessageAge,
                maxFirstLevelRetryCount,
                firstLevelRetryQueueCapacity,
                processingQueueCapacity,
                messageConsumersCount,
                messageProcessorsCount
            });

            var internalQueue = new InternalMessageQueue(processingQueueCapacity);
            var rejectManager = new RejectManager(logFactory);
            var retryManager  = new RetryManager
                                (
                logFactory,
                maxFirstLevelRetryMessageAge,
                maxFirstLevelRetryCount,
                firstLevelRetryQueueCapacity,
                internalQueue
                                );

            var messageConsumers = new List <IMessageConsumer>(messageConsumersCount);

            for (var i = 0; i < messageConsumersCount; i++)
            {
                messageConsumers.Add(new MessageConsumer
                                     (
                                         connection,
                                         internalQueue,
                                         logFactory,
                                         queueName
                                     ));
            }

            var messageProcessors = new List <IMessageProcessor>(messageConsumersCount);

            for (var i = 0; i < messageProcessorsCount; i++)
            {
                messageProcessors.Add(new MessageProcessor
                                      (
                                          defaultFirstLevelRetryTimeout,
                                          formatterResolver,
                                          internalQueue,
                                          logFactory,
                                          repliesPublisher,
                                          rejectManager,
                                          retryManager,
                                          serviceProvider,
                                          subscriptionsRegistry
                                      ));
            }

            using (var channel = connection.CreateModel())
            {
                channel.BasicQos(0, 100, false);
                channel.QueueDeclare(queueName, true, false, false, null);

                log.Info($"Start receiving messages from the exchange {exchangeName} via the queue {queueName}:");

                foreach (var subscription in subscriptionsRegistry.GetAllSubscriptions())
                {
                    log.Info($"Binding message {subscription.RoutingKey}...");

                    channel.QueueBind(queueName, exchangeName, subscription.RoutingKey, null);
                }
            }

            return(new MessageSubscriber
                   (
                       messageConsumers,
                       messageProcessors,
                       rejectManager,
                       retryManager
                   ));
        }
예제 #3
0
        /// <inheritdoc />
        public void Subscribe(IMessageSubscriptionsRegistry subscriptionsRegistry,
                              string listeningExchangeName,
                              string listeningRoute,
                              TimeSpan?defaultFirstLevelRetryTimeout = null,
                              TimeSpan?maxFirstLevelRetryMessageAge  = null,
                              int maxFirstLevelRetryCount            = 5,
                              int firstLevelRetryQueueCapacity       = 10000,
                              int processingQueueCapacity            = 1000,
                              int messageConsumersCount  = 4,
                              int messageProcessorsCount = 8,
                              string replyExchangeName   = null)
        {
            if (string.IsNullOrWhiteSpace(listeningExchangeName))
            {
                throw new ArgumentException("Should be not empty string", nameof(listeningExchangeName));
            }

            if (string.IsNullOrWhiteSpace(listeningRoute))
            {
                throw new ArgumentException("Should be not empty string", nameof(listeningRoute));
            }

            if (subscriptionsRegistry == null)
            {
                throw new ArgumentNullException(nameof(subscriptionsRegistry));
            }

            if (processingQueueCapacity <= 0)
            {
                throw new ArgumentOutOfRangeException(nameof(processingQueueCapacity), processingQueueCapacity, "Should be a positive number.");
            }

            if (maxFirstLevelRetryCount <= 0)
            {
                throw new ArgumentOutOfRangeException(nameof(maxFirstLevelRetryCount), maxFirstLevelRetryCount, "Should be a positive number.");
            }

            if (messageConsumersCount <= 0)
            {
                throw new ArgumentOutOfRangeException(nameof(messageConsumersCount), messageConsumersCount, "Should be a positive number.");
            }

            if (messageProcessorsCount <= 0)
            {
                throw new ArgumentOutOfRangeException(nameof(messageProcessorsCount), messageProcessorsCount, "Should be a positive number.");
            }

            if (_connection == null)
            {
                throw new InvalidOperationException("RabbitMqEndpoint should be started first");
            }

            var listeningQueueName = $"{listeningExchangeName}.{listeningRoute}";

            Func <string, IMessagePublisher> repliesPublisher = null;

            if (replyExchangeName != null)
            {
                repliesPublisher = correlationId => CreatePublisher(replyExchangeName, correlationId);
            }

            var subscriber = MessageSubscriber.Create
                             (
                _serviceProvider,
                subscriptionsRegistry,
                _connection,
                _logFactory,
                _formatterResolver,
                repliesPublisher,
                listeningExchangeName,
                listeningQueueName,
                defaultFirstLevelRetryTimeout ?? TimeSpan.FromSeconds(30),
                maxFirstLevelRetryMessageAge ?? TimeSpan.FromMinutes(10),
                maxFirstLevelRetryCount,
                firstLevelRetryQueueCapacity,
                processingQueueCapacity,
                messageConsumersCount,
                messageProcessorsCount);

            _subscribers.Add(subscriber);
        }