public async Task <PullResult> Pull(ChannelClient client, TmqMessage request) { QueueMessage message = null; await _queue.RunInListSync(() => { //pull from prefential messages if (_queue.HighPriorityLinkedList.Count > 0) { message = _queue.HighPriorityLinkedList.First.Value; _queue.HighPriorityLinkedList.RemoveFirst(); if (message != null) { message.IsInQueue = false; } } //if there is no prefential message, pull from standard messages if (message == null && _queue.RegularLinkedList.Count > 0) { message = _queue.RegularLinkedList.First.Value; _queue.RegularLinkedList.RemoveFirst(); if (message != null) { message.IsInQueue = false; } } }); //there is no pullable message if (message == null) { await client.Client.SendAsync(MessageBuilder.ResponseStatus(request, KnownContentTypes.NotFound)); return(PullResult.Empty); } try { await ProcessPull(client, request, message); } catch (Exception ex) { _queue.Info.AddError(); try { Decision decision = await _queue.DeliveryHandler.ExceptionThrown(_queue, message, ex); await _queue.ApplyDecision(decision, message); if (decision.KeepMessage && !message.IsInQueue) { _queue.AddMessage(message, false); } } catch //if developer does wrong operation, we should not stop { } } return(PullResult.Success); }