Esempio n. 1
0
        /// <summary>
        /// Uses the RMQ bound consumers.
        /// </summary>
        /// <param name="serviceProvider">The service provider.</param>
        /// <param name="cancellationToken">The cancellation token.</param>
        /// <param name="onException">The on exception.</param>
        public static void UseRMQBoundConsumers(this IServiceProvider serviceProvider, CancellationToken cancellationToken, Action <Exception> onException = null)
        {
            var consumerFactory  = new RMQConsumerFactory(new RMQConnectionFactory());
            var subcriberFactory = new RMQSubscriberFactory(new RMQConnectionFactory());
            var logFactory       = serviceProvider.GetService <ILoggerFactory>();

            foreach (var type in _Consumers.Keys)
            {
                Task.Run(async() =>
                {
                    var logger         = logFactory.CreateLogger(type);
                    var options        = _Consumers[type];
                    var consumer       = (IRMQConsumer)null;
                    var isTextConsumer = typeof(IRMQBoundConsumerText).IsAssignableFrom(type);

                    if (options is RMQBuilderSubscriptionOptions)
                    {
                        var subOptions = (options as RMQBuilderSubscriptionOptions);

                        if (isTextConsumer)
                        {
                            consumer = subcriberFactory.CreateText(subOptions.ConnectionSettings, subOptions.ExchangeSettings, subOptions.QueueSettings);
                        }
                        else
                        {
                            consumer = subcriberFactory.CreateBytes(subOptions.ConnectionSettings, subOptions.ExchangeSettings, subOptions.QueueSettings);
                        }
                    }
                    else // standard consumer
                    {
                        if (isTextConsumer)
                        {
                            consumer = consumerFactory.CreateText(options.ConnectionSettings, options.QueueSettings);
                        }
                        else
                        {
                            consumer = consumerFactory.CreateBytes(options.ConnectionSettings, options.QueueSettings);
                        }
                    }

                    using (consumer)
                    {
                        consumer.Mode = ConsumerMode.OnNoMessage_ReturnNull;

                        while (cancellationToken.IsCancellationRequested == false)
                        {
                            try
                            {
                                try
                                {
                                    if (consumer is IRMQConsumerText)
                                    {
                                        var message = (consumer as IRMQConsumerText).Receive(1000);
                                        if (message != null)
                                        {
                                            using (var scope = serviceProvider.CreateScope())
                                            {
                                                var loopConsumer = scope.ServiceProvider.GetService(type) as IRMQBoundConsumerText;
                                                await loopConsumer.OnMessageAsync(message, cancellationToken);
                                                message.Acknowledge();
                                            }
                                        }
                                    }
                                    else // bytes
                                    {
                                        var message = (consumer as IRMQConsumerBytes).Receive(1000);
                                        if (message != null)
                                        {
                                            using (var scope = serviceProvider.CreateScope())
                                            {
                                                var loopConsumer = scope.ServiceProvider.GetService(type) as IRMQBoundConsumerBytes;
                                                await loopConsumer.OnMessageAsync(message);
                                                message.Acknowledge();
                                            }
                                        }
                                    }
                                }
                                catch (TimeoutException)
                                {
                                }
                                catch (MessageException ex)
                                {
                                    switch (ex.ExceptionCode)
                                    {
                                    case MessageExceptionCode.ExclusiveLock:
                                        await Task.Delay(1000);
                                        break;

                                    default:
                                        throw;
                                    }
                                }
                            }
                            catch (Exception ex)
                            {
                                consumer.ClearCacheBuffer();

                                try
                                {
                                    onException?.Invoke(ex);
                                }
                                catch (Exception ex2)
                                {
                                    var aggregateException = new AggregateException("RMQ Consumer Error (OnException Handler fault).", new[] { ex, ex2 });
                                    logger.LogError(aggregateException, aggregateException.Message);
                                }
                            }
                        }
                    }
                });
            }
        }