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); }
/// <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)); }
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); } }