コード例 #1
0
        private CompositeSubscription CreateSubscription <T>(string subscriptionName, uint maxPriorityLevel, Func <IModel, string, IBasicConsumer> createConsumer, Type comparerType)
        {
            var comparer = TryGetComparer(comparerType);
            var compositeSubscription = new CompositeSubscription();
            var maxSize         = Global.PreFetchSize * ((int)maxPriorityLevel + 1);
            var priorityQueue   = new InMemoryPriorityQueue <GenericPriorityMessage <BasicDeliverEventArgs> >(maxSize, comparer);
            var sharedSemaphore = string.Format("{0}{1}", subscriptionName, Guid.NewGuid());

            for (uint level = 0; level <= maxPriorityLevel; level++)
            {
                var subscription = new Subscription {
                    SubscriptionName = subscriptionName
                };
                uint priority = level;
                var  id       = Guid.NewGuid();

                Action subscriptionAction = () =>
                {
                    subscription.QueueName = _routeFinder.FindQueueName <T>(subscriptionName) + PriorityQueuesRabbitSetup.GlobalPriorityQueueSuffix.Get(typeof(T), priority);
                    if (string.IsNullOrEmpty(subscription.ConsumerTag))
                    {
                        // Keep the key here because it's used for the key indexes of internal cache
                        subscription.ConsumerTag = string.Format("{0}-{1}", subscriptionName, Guid.NewGuid());
                    }
                    var channel = _connection.CreateChannel();
                    channel.ModelShutdown += (c, reason) =>
                    {
                        RaiseConsumerDisconnectedEvent(subscription);
                        TryReconnect(c, id, reason);
                    };
                    if (Global.PreFetchSize <= ushort.MaxValue)
                    {
                        channel.BasicQos(0, (ushort)Global.PreFetchSize, false);
                    }
                    else
                    {
                        _watcher.WarnFormat("The prefetch size is too high {0}, the queue will prefetch all the msgs", Global.PreFetchSize);
                    }

                    _createdChannels.Add(channel);

                    var consumer         = createConsumer(channel, subscription.ConsumerTag);
                    var priorityConsumer = consumer as PriorityBurrowConsumer;
                    if (priorityConsumer == null)
                    {
                        throw new NotSupportedException(string.Format("Expected PriorityBurrowConsumer but was {0}", consumer == null ? "NULL" : consumer.GetType().Name));
                    }

                    priorityConsumer.Init(priorityQueue, compositeSubscription, priority, sharedSemaphore);
                    priorityConsumer.ConsumerTag = subscription.ConsumerTag;
                    subscription.SetChannel(channel);

                    //NOTE: The message will still be on the Unacknowledged list until it's processed and the method
                    //      DoAck is call.
                    channel.BasicConsume(subscription.QueueName,
                                         false /* noAck, must be false */,
                                         subscription.ConsumerTag, priorityConsumer);
                    _watcher.InfoFormat("Subscribed to: {0} with subscriptionName: {1}",
                                        subscription.QueueName,
                                        subscription.SubscriptionName);
                    priorityConsumer.Ready();
                };

                _subscribeActions[id] = subscriptionAction;
                TrySubscribe(subscriptionAction);
                compositeSubscription.AddSubscription(subscription);
            }
            return(compositeSubscription);
        }
コード例 #2
0
        private CompositeSubscription CreateSubscription <T>(IPrioritySubscriptionOption subscriptionOption, Func <IModel, IBasicConsumer> createConsumer)
        {
            var comparer = TryGetComparer(subscriptionOption.ComparerType);
            var compositeSubscription = new CompositeSubscription();

            uint maxSize = 0;

            for (uint level = 0; level <= subscriptionOption.MaxPriorityLevel; level++)
            {
                maxSize += GetProperPrefetchSize(subscriptionOption, level);
            }
            var priorityQueue = new InMemoryPriorityQueue <GenericPriorityMessage <BasicDeliverEventArgs> >(maxSize, comparer);

            var sharedSemaphore = string.Format("{0}{1}", subscriptionOption.SubscriptionName, Guid.NewGuid());

            for (uint level = 0; level <= subscriptionOption.MaxPriorityLevel; level++)
            {
                var subscription = new Subscription {
                    SubscriptionName = subscriptionOption.SubscriptionName
                };
                uint priority = level;
                var  id       = Guid.NewGuid();

                Action subscriptionAction = () =>
                {
                    subscription.QueueName = GetPriorityQueueName <T>(subscriptionOption, priority);
                    if (string.IsNullOrEmpty(subscription.ConsumerTag))
                    {
                        // Keep the key here because it's used for the key indexes of internal cache
                        subscription.ConsumerTag = string.Format("{0}-{1}", subscriptionOption.SubscriptionName, Guid.NewGuid());
                    }
                    var channel = _connection.CreateChannel();
                    channel.ModelShutdown += (o, reason) =>
                    {
                        RaiseConsumerDisconnectedEvent(subscription);
                        TryReconnect((IModel)o, id, reason);
                    };

                    var prefetchSize = GetProperPrefetchSize(subscriptionOption, priority);
                    channel.BasicQos(0, prefetchSize, false);

                    _createdChannels.Add(channel);

                    var consumer         = createConsumer(channel);
                    var priorityConsumer = consumer as PriorityBurrowConsumer;
                    if (priorityConsumer == null)
                    {
                        throw new NotSupportedException(string.Format("Expected PriorityBurrowConsumer but was {0}", consumer == null ? "NULL" : consumer.GetType().Name));
                    }

                    priorityConsumer.Init(priorityQueue, compositeSubscription, priority, sharedSemaphore);
                    priorityConsumer.ConsumerTag = subscription.ConsumerTag;
                    Subscription.OutstandingDeliveryTags[subscription.ConsumerTag] = new List <ulong>();
                    subscription.SetChannel(channel);

                    //NOTE: The message will still be on the Unacknowledged list until it's processed and the method
                    //      DoAck is call.
                    channel.BasicConsume(subscription.QueueName,
                                         false /* noAck, must be false */,
                                         subscription.ConsumerTag, priorityConsumer);
                    _watcher.InfoFormat("Subscribed to: {0} with subscriptionName: {1}",
                                        subscription.QueueName,
                                        subscription.SubscriptionName);
                    priorityConsumer.Ready();
                };

                _subscribeActions[id] = subscriptionAction;
                TrySubscribe(subscriptionAction);
                compositeSubscription.AddSubscription(subscription);
            }
            return(compositeSubscription);
        }