public async Task PullCount(int count)
        {
            TestHorseMq server = new TestHorseMq();
            await server.Initialize();

            int port = server.Start();

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

            for (int i = 0; i < 25; i++)
            {
                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);

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

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

            Assert.Equal(count, container.ReceivedCount);
            Assert.Equal(PullProcess.Completed, container.Status);
        }
        /// <summary>
        /// Request a message from Pull queue
        /// </summary>
        public async Task <PullContainer> Pull(PullRequest request, Func <int, HorseMessage, Task> actionForEachMessage = null)
        {
            HorseMessage message = new HorseMessage(MessageType.QueuePullRequest, request.Queue);

            message.SetMessageId(_client.UniqueIdGenerator.Create());
            message.AddHeader(HorseHeaders.COUNT, request.Count);

            if (request.ClearAfter == ClearDecision.AllMessages)
            {
                message.AddHeader(HorseHeaders.CLEAR, "all");
            }
            else if (request.ClearAfter == ClearDecision.PriorityMessages)
            {
                message.AddHeader(HorseHeaders.CLEAR, "High-Priority");
            }
            else if (request.ClearAfter == ClearDecision.Messages)
            {
                message.AddHeader(HorseHeaders.CLEAR, "Default-Priority");
            }

            if (request.GetQueueMessageCounts)
            {
                message.AddHeader(HorseHeaders.INFO, "yes");
            }

            if (request.Order == MessageOrder.LIFO)
            {
                message.AddHeader(HorseHeaders.ORDER, HorseHeaders.LIFO);
            }

            foreach (KeyValuePair <string, string> pair in request.RequestHeaders)
            {
                message.AddHeader(pair.Key, pair.Value);
            }

            PullContainer container = new PullContainer(message.MessageId, request.Count, actionForEachMessage);

            lock (PullContainers)
                PullContainers.Add(message.MessageId, container);

            HorseResult sent = await _client.SendAsync(message);

            if (sent.Code != HorseResultCode.Ok)
            {
                lock (PullContainers)
                    PullContainers.Remove(message.MessageId);

                container.Complete("Error");
            }

            return(await container.GetAwaitableTask());
        }
        public async Task RequestAcknowledge()
        {
            TestHorseMq server = new TestHorseMq();
            await server.Initialize();

            int port = server.Start(300, 300);

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

            Assert.NotNull(queue);
            queue.Options.Acknowledge        = QueueAckDecision.JustRequest;
            queue.Options.AcknowledgeTimeout = TimeSpan.FromSeconds(15);

            HorseClient consumer = new HorseClient();

            consumer.AutoAcknowledge = true;
            consumer.ClientId        = "consumer";

            await consumer.ConnectAsync("hmq://localhost:" + port);

            Assert.True(consumer.IsConnected);

            bool msgReceived = false;

            consumer.MessageReceived += (c, m) => msgReceived = true;
            HorseResult joined = await consumer.Queues.Subscribe("pull-a", true);

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

            HorseClient producer = new HorseClient();

            producer.ResponseTimeout = TimeSpan.FromSeconds(15);
            await producer.ConnectAsync("hmq://localhost:" + port);

            Assert.True(producer.IsConnected);

            Task <HorseResult> taskAck = producer.Queues.Push("pull-a", "Hello, World!", true);

            await Task.Delay(500);

            Assert.False(taskAck.IsCompleted);
            Assert.False(msgReceived);
            Assert.Single(queue.Messages);

            consumer.PullTimeout = TimeSpan.FromDays(1);

            PullContainer pull = await consumer.Queues.Pull(PullRequest.Single("pull-a"));

            Assert.Equal(PullProcess.Completed, pull.Status);
            Assert.Equal(1, pull.ReceivedCount);
            Assert.NotEmpty(pull.ReceivedMessages);
        }
        /// <inheritdoc />
        public Task <PullContainer> Pull(PullRequest request,
                                         Func <int, HorseMessage, Task> actionForEachMessage = null)
        {
            HorseClient client = _connector.GetClient();

            if (client == null)
            {
                PullContainer con = new PullContainer(null, 0, null);
                con.Complete(HorseHeaders.ERROR);
                return(con.GetAwaitableTask());
            }

            return(client.Queues.Pull(request, actionForEachMessage));
        }
        public async Task SendAndPull()
        {
            TestHorseMq server = new TestHorseMq();
            await server.Initialize();

            int port = server.Start(300, 300);

            HorseClient consumer = new HorseClient();

            consumer.ClientId = "consumer";
            await consumer.ConnectAsync("hmq://localhost:" + port);

            Assert.True(consumer.IsConnected);
            HorseResult joined = await consumer.Queues.Subscribe("pull-a", true);

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

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

            Assert.True(producer.IsConnected);

            await producer.Queues.Push("pull-a", "Hello, World!", false);

            await Task.Delay(700);

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

            Assert.NotNull(queue);
            Assert.Single(queue.Messages);

            PullRequest request = new PullRequest();

            request.Queue                 = "pull-a";
            request.Count                 = 1;
            request.ClearAfter            = ClearDecision.None;
            request.GetQueueMessageCounts = false;
            request.Order                 = MessageOrder.FIFO;

            PullContainer container1 = await consumer.Queues.Pull(request);

            Assert.Equal(PullProcess.Completed, container1.Status);
            Assert.NotEmpty(container1.ReceivedMessages);

            PullContainer container2 = await consumer.Queues.Pull(request);

            Assert.Equal(PullProcess.Empty, container2.Status);
            Assert.Empty(container2.ReceivedMessages);
        }
        public async Task PullOrder(bool?fifo)
        {
            TestHorseMq server = new TestHorseMq();
            await server.Initialize();

            int port = server.Start();

            HorseQueue queue = server.Server.FindQueue("pull-a");
            await queue.Push("First Message");

            await queue.Push("Second Message");

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

            PullRequest request = new PullRequest
            {
                Queue = "pull-a",
                Count = 1,
                Order = !fifo.HasValue || fifo.Value ? MessageOrder.FIFO : MessageOrder.LIFO
            };

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

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

            HorseMessage msg = container.ReceivedMessages.FirstOrDefault();

            Assert.NotNull(msg);

            string content = msg.GetStringContent();

            if (fifo.HasValue && !fifo.Value)
            {
                Assert.Equal("Second Message", content);
            }
            else
            {
                Assert.Equal("First Message", content);
            }
        }
        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);
            }
        }