예제 #1
0
        public async Task <PullResult> Pull(QueueClient client, HorseMessage request)
        {
            int index = 1;
            int count = FindCount(request);

            if (count < 1)
            {
                await client.Client.SendAsync(MessageBuilder.CreateNoContentPullResponse(request, HorseHeaders.UNACCEPTABLE));

                return(PullResult.Unacceptable);
            }

            ClearDecision clear    = FindClearDecision(request);
            bool          sendInfo = FindInfoRequest(request);
            bool          fifo     = FindOrder(request);

            Tuple <QueueMessage, int, int> messageTuple = await DequeueMessage(fifo, sendInfo, count == index?clear : ClearDecision.None);

            //there is no pullable message
            if (messageTuple.Item1 == null)
            {
                await client.Client.SendAsync(MessageBuilder.CreateNoContentPullResponse(request, HorseHeaders.EMPTY));

                return(PullResult.Empty);
            }

            List <KeyValuePair <string, string> > headers     = new List <KeyValuePair <string, string> >();
            KeyValuePair <string, string>         requestId   = new KeyValuePair <string, string>(HorseHeaders.REQUEST_ID, request.MessageId);
            KeyValuePair <string, string>         countHeader = new KeyValuePair <string, string>(HorseHeaders.COUNT, count.ToString());

            while (index <= count)
            {
                QueueMessage message = messageTuple.Item1;
                if (message == null)
                {
                    break;
                }

                try
                {
                    headers.Add(requestId);
                    headers.Add(countHeader);
                    headers.Add(new KeyValuePair <string, string>(HorseHeaders.INDEX, index.ToString()));

                    if (sendInfo)
                    {
                        headers.Add(new KeyValuePair <string, string>(HorseHeaders.PRIORITY_MESSAGES, messageTuple.Item2.ToString()));
                        headers.Add(new KeyValuePair <string, string>(HorseHeaders.MESSAGES, messageTuple.Item3.ToString()));
                    }

                    bool processed = await ProcessPull(client, request, message, headers);

                    if (!processed)
                    {
                        break;
                    }

                    index++;
                    messageTuple = await DequeueMessage(fifo, sendInfo, count == index?clear : ClearDecision.None);

                    headers.Clear();
                }
                catch (Exception ex)
                {
                    _queue.Info.AddError();
                    try
                    {
                        Decision decision = await _queue.DeliveryHandler.ExceptionThrown(_queue, message, ex);

                        await _queue.ApplyDecision(decision, message);

                        if (!message.IsInQueue)
                        {
                            if (decision.PutBack == PutBackDecision.Start)
                            {
                                _queue.AddMessage(message, false);
                            }
                            else if (decision.PutBack == PutBackDecision.End)
                            {
                                _queue.AddMessage(message);
                            }
                        }
                    }
                    catch //if developer does wrong operation, we should not stop
                    {
                    }
                }
            }

            await client.Client.SendAsync(MessageBuilder.CreateNoContentPullResponse(request, HorseHeaders.END));

            return(PullResult.Success);
        }
예제 #2
0
        /// <summary>
        /// Finds and dequeues a message from the queue.
        /// If there is not message, returns null
        /// </summary>
        private async Task <Tuple <QueueMessage, int, int> > DequeueMessage(bool fifo, bool getInfo, ClearDecision clear)
        {
            QueueMessage message          = null;
            int          prioMessageCount = 0;
            int          messageCount     = 0;

            await _queue.RunInListSync(() =>
            {
                //pull from prefential messages
                if (_queue.PriorityMessagesList.Count > 0)
                {
                    if (fifo)
                    {
                        // ReSharper disable once PossibleNullReferenceException
                        message = _queue.PriorityMessagesList.First.Value;
                        _queue.PriorityMessagesList.RemoveFirst();
                    }
                    else
                    {
                        // ReSharper disable once PossibleNullReferenceException
                        message = _queue.PriorityMessagesList.Last.Value;
                        _queue.PriorityMessagesList.RemoveLast();
                    }

                    if (message != null)
                    {
                        message.IsInQueue = false;
                    }
                }

                //if there is no prefential message, pull from standard messages
                if (message == null && _queue.MessagesList.Count > 0)
                {
                    if (fifo)
                    {
                        // ReSharper disable once PossibleNullReferenceException
                        message = _queue.MessagesList.First.Value;
                        _queue.MessagesList.RemoveFirst();
                    }
                    else
                    {
                        // ReSharper disable once PossibleNullReferenceException
                        message = _queue.MessagesList.Last.Value;
                        _queue.MessagesList.RemoveLast();
                    }

                    if (message != null)
                    {
                        message.IsInQueue = false;
                    }
                }

                if (getInfo)
                {
                    prioMessageCount = _queue.PriorityMessageCount();
                    messageCount     = _queue.MessageCount();
                }

                if (clear == ClearDecision.All)
                {
                    _queue.ClearAllMessages();
                }

                else if (clear == ClearDecision.HighPriority)
                {
                    _queue.ClearHighPriorityMessages();
                }

                else if (clear == ClearDecision.DefaultPriority)
                {
                    _queue.ClearRegularMessages();
                }
            });

            return(new Tuple <QueueMessage, int, int>(message, prioMessageCount, messageCount));
        }
예제 #3
0
        public async Task PullClearAfter(int count, bool priorityMessages, bool messages)
        {
            TestHorseMq server = new TestHorseMq();
            await server.Initialize();

            int port = server.Start();

            HorseQueue queue = server.Server.FindQueue("pull-a");

            for (int i = 0; i < 5; i++)
            {
                await queue.Push("Hello, World");

                await queue.Push("Hello, World");
            }

            HorseClient client = new HorseClient();
            await client.ConnectAsync("hmq://localhost:" + port);

            HorseResult joined = await client.Queues.Subscribe("pull-a", true);

            Assert.Equal(HorseResultCode.Ok, joined.Code);

            ClearDecision clearDecision = ClearDecision.None;

            if (priorityMessages && messages)
            {
                clearDecision = ClearDecision.AllMessages;
            }
            else if (priorityMessages)
            {
                clearDecision = ClearDecision.PriorityMessages;
            }
            else if (messages)
            {
                clearDecision = ClearDecision.Messages;
            }

            PullRequest request = new PullRequest
            {
                Queue      = "pull-a",
                Count      = count,
                ClearAfter = clearDecision
            };

            PullContainer container = await client.Queues.Pull(request);

            Assert.Equal(count, container.ReceivedCount);

            Assert.Equal(PullProcess.Completed, container.Status);

            if (priorityMessages)
            {
                Assert.Empty(queue.PriorityMessages);
            }

            if (messages)
            {
                Assert.Empty(queue.Messages);
            }
        }