Exemple #1
0
        private async Task RandomClient(IWorkContext context, MonitorReport report, int clientNumber, CancellationToken token)
        {
            string          agentName = $"{_options.AgentName}_Send_{clientNumber}";
            AgentContractV1 agent     = (await _client.Message.GetAgentId(context, _options.QueueName, agentName)).Value;

            using (var monitor = new MonitorRate(report, agentName))
            {
                while (!token.IsCancellationRequested)
                {
                    try
                    {
                        EnqueueMessageContractV1          request  = CreateMessage(context, agent.AgentId, _options.QueueName);
                        RestResponse <EnqueuedContractV1> response = await _client.Message.EnqueueMessage(context, request);

                        if (response.StatusCode != HttpStatusCode.OK)
                        {
                            monitor.IncrementError();
                            continue;
                        }

                        monitor.IncrementNew();

                        await Utility.Delay(_options.Delay, token);
                    }
                    catch
                    {
                        monitor.IncrementError();
                    }
                }
            }
        }
Exemple #2
0
 public MessageEvent(T message, MessageContractV1 contract, AgentContractV1 agent, bool useSettle)
 {
     Message   = message;
     Contract  = contract;
     Agent     = agent;
     UseSettle = useSettle;
 }
Exemple #3
0
        public async Task ListActiveQueueTestApi()
        {
            const int messageSize = 100;
            var       context     = _workContext.WithTag(_tag);

            AgentContractV1 agent = await _utility.SetupAgentAndQueue(_queueName, _agentName);

            var messageList = new List <EnqueueMessageContractV1>();

            foreach (int index in Enumerable.Range(0, messageSize))
            {
                EnqueueMessageContractV1 message = _utility.CreateMessage(context, agent.AgentId, _queueName);
                messageList.Add(message);

                await _client.Message.EnqueueMessage(context, message);
            }

            await _utility.VerifyQueue(context, _queueName, messageSize, 0);

            IEnumerable <MessageContractV1> activeMessage = (await _client.Message.GetActiveMessages(context, _queueName)).Value.Items;

            var zip = messageList
                      .OrderBy(x => x.ClientMessageId)
                      .Zip(activeMessage.OrderBy(x => x.ClientMessageId), (f, s) => new Tuple <EnqueueMessageContractV1, MessageContractV1>(f, s));
        }
        public async Task SimpleScheduleSuccessTestApi()
        {
            var context = _workContext.WithTag(_tag);

            AgentContractV1 agent = await _utility.SetupAgentAndQueue(_queueName, _agentName);

            EnqueueMessageContractV1 message = _utility.CreateMessage(context, agent.AgentId, _queueName);

            message.ScheduleDate = DateTime.UtcNow.AddSeconds(2);

            await _client.Message.EnqueueMessage(context, message);

            await _utility.VerifyQueue(context, _queueName, 0, 1);

            MessageContractV1 readMessage = (await _client.Message.DequeueMessageAndDelete(context, _queueName, null)).Value;

            readMessage.Should().BeNull();

            await Task.Delay(TimeSpan.FromSeconds(10));

            readMessage = (await _client.Message.DequeueMessageAndDelete(context, _queueName, null)).Value;
            _utility.VerifyMessage(message, readMessage, agent.AgentId, false);

            HistoryContractV1 history = (await _client.History.GetHistory(context, readMessage.MessageId)).Value;

            _utility.VerifyHistoryMessage(readMessage, history, _queueName, _agentName);
        }
Exemple #5
0
        public async Task SimpleEnqueueWithLockSuccessTestApi()
        {
            var context = _workContext.WithTag(_tag);

            AgentContractV1 agent = await _utility.SetupAgentAndQueue(_queueName, _agentName);

            EnqueueMessageContractV1 message = _utility.CreateMessage(context, agent.AgentId, _queueName);

            await _client.Message.EnqueueMessage(context, message);

            await _utility.VerifyQueue(context, _queueName, 1, 0);

            MessageContractV1 readMessage = (await _client.Message.DequeueMessageWithLock(context, _queueName, agent, null)).Value;

            _utility.VerifyMessage(message, readMessage, agent.AgentId, true);

            var settleMessage = new SettleMessageContractV1
            {
                AgentId    = agent.AgentId,
                QueueName  = _queueName,
                SettleType = SettleType.Processed,
                MessageId  = readMessage.MessageId,
            };

            await _client.Message.SettleMessage(context, settleMessage);

            await _utility.VerifyQueue(context, _queueName, 0, 0);

            HistoryContractV1 history = (await _client.History.GetHistory(context, readMessage.MessageId)).Value;

            _utility.VerifyHistoryMessage(readMessage, history, _queueName, _agentName);
        }
        public async Task MultipleScheduleSuccessTestApi()
        {
            const int scheduleSize = 10;
            var       context      = _workContext.WithTag(_tag);

            AgentContractV1 agent = await _utility.SetupAgentAndQueue(_queueName, _agentName);

            var list = new List <EnqueueMessageContractV1>();

            foreach (var item in Enumerable.Range(0, scheduleSize))
            {
                EnqueueMessageContractV1 message = _utility.CreateMessage(context, agent.AgentId, _queueName);
                message.ScheduleDate = DateTime.UtcNow.AddSeconds(2);

                await _client.Message.EnqueueMessage(context, message);

                list.Add(message);
            }

            await _utility.VerifyQueue(context, _queueName, 0, scheduleSize);

            MessageContractV1 readMessage = (await _client.Message.DequeueMessageAndDelete(context, _queueName, null)).Value;

            readMessage.Should().BeNull();

            await Task.Delay(TimeSpan.FromSeconds(10));

            var readList = new List <MessageContractV1>();

            foreach (var item in Enumerable.Range(0, scheduleSize))
            {
                readMessage = (await _client.Message.DequeueMessageAndDelete(context, _queueName, null)).Value;
                readMessage.Should().NotBeNull();

                readList.Add(readMessage);
            }

            readList.Count.Should().Be(scheduleSize);

            readMessage = (await _client.Message.DequeueMessageAndDelete(context, _queueName, null)).Value;
            readMessage.Should().BeNull();

            var zip = list
                      .OrderBy(x => x.ClientMessageId)
                      .Zip(readList.OrderBy(x => x.ClientMessageId), (f, s) => new Tuple <EnqueueMessageContractV1, MessageContractV1>(f, s));

            foreach (var item in zip)
            {
                _utility.VerifyMessage(item.Item1, item.Item2, agent.AgentId, false);
            }

            await _utility.VerifyQueue(context, _queueName, 0, 0);

            foreach (var item in readList)
            {
                HistoryContractV1 history = (await _client.History.GetHistory(context, item.MessageId)).Value;
                _utility.VerifyHistoryMessage(item, history, _queueName, _agentName);
            }
        }
        /// <summary>
        /// Process dequeue operations, monitors for new messages and calls process message lambda.
        /// </summary>
        /// <param name="context">context</param>
        /// <param name="processMessage">lambda to call when a message is received</param>
        /// <param name="token">cancellation token, this cancel's the processing loop</param>
        /// <param name="useSettle">use settle operations, true messages are locked and must be settled, false = read and delete (implicit)</param>
        /// <param name="wait">true for long polling</param>
        /// <returns>task</returns>
        public async Task ProcessDequeue(IWorkContext context, Func <IWorkContext, T, MessageEvent, Task <bool> > processMessage, CancellationToken token, bool useSettle = true, bool wait = true)
        {
            Verify.IsNotNull(nameof(processMessage), processMessage);
            context = context.WithTag(_tag);

            await EnableQueue(context);

            RestResponse <MessageContractV1> readMessage = null;
            AgentContractV1 agent = await GetAgent(context);

            TimeSpan?waitFor = wait ? TimeSpan.FromSeconds(15) : (TimeSpan?)null;

            while (!token.IsCancellationRequested)
            {
                if (!useSettle)
                {
                    readMessage = await Client.Message.DequeueMessageAndDelete(context, QueueName, waitFor, token);
                }
                else
                {
                    readMessage = await Client.Message.DequeueMessageWithLock(context, QueueName, agent, waitFor, token);
                }

                if (readMessage == null || readMessage.StatusCode == HttpStatusCode.NoContent)
                {
                    readMessage = null;
                    try
                    {
                        await Task.Delay(TimeSpan.FromMilliseconds(500), token);
                    }
                    catch
                    {
                        return;
                    }

                    continue;
                }

                try
                {
                    var  messageEvent = new MessageEvent(readMessage.Value, token, agent);
                    bool success      = await processMessage(context, readMessage.Value.Deserialize <T>(), messageEvent);

                    if (useSettle)
                    {
                        await SettleMessage(context, readMessage.Value.MessageId, success?SettleType.Processed : SettleType.Rejected);
                    }
                }
                catch (Exception ex)
                {
                    ToolboxEventSource.Log.Error(context, "Exception raised", ex);

                    if (useSettle && readMessage != null && readMessage.StatusCode == HttpStatusCode.OK)
                    {
                        await SettleMessage(context, readMessage.Value.MessageId, SettleType.Rejected, ex.ToString());
                    }
                }
            }
        }
        /// <summary>
        /// Get cached agent or ask the service
        /// </summary>
        /// <param name="context">context</param>
        /// <returns>agent contract</returns>
        private async Task <AgentContractV1> GetAgent(IWorkContext context)
        {
            if (_agent != null)
            {
                return(_agent);
            }

            return(_agent = (await Client.Message.GetAgentId(context, QueueName, AgentName)).Value);
        }
        /// <summary>
        /// Settle message for Dequeue and lock operations
        /// </summary>
        /// <param name="context">context</param>
        /// <param name="messageId">message id</param>
        /// <param name="settleType">settle type</param>
        /// <param name="errorMessage">error message (optional)</param>
        /// <returns>task</returns>
        private async Task SettleMessage(IWorkContext context, long messageId, SettleType settleType, string errorMessage = null)
        {
            AgentContractV1 agent = await GetAgent(context);

            var settleMessage = new SettleMessageContractV1
            {
                AgentId      = agent.AgentId,
                QueueName    = QueueName,
                SettleType   = settleType,
                MessageId    = messageId,
                ErrorMessage = errorMessage
            };

            await Client.Message.SettleMessage(context, settleMessage);
        }
        /// <summary>
        /// Create message with GUID as client message id
        /// </summary>
        /// <param name="context">context</param>
        /// <param name="message">message to serialize</param>
        /// <returns>message contract</returns>
        private async Task <EnqueueMessageContractV1> CreateMessage(IWorkContext context, T message)
        {
            Verify.IsNotNull(nameof(message), message);

            AgentContractV1 agent = await GetAgent(context);

            return(new EnqueueMessageContractV1
            {
                QueueName = QueueName,
                AgentId = agent.AgentId,
                ClientMessageId = Guid.NewGuid().ToString(),
                Cv = context.Cv,
                Payload = JsonConvert.SerializeObject(message),
            });
        }
        public async Task QueueReadWriteTestApi()
        {
            var context = _workContext.WithTag(_tag);

            AgentContractV1 agent = await _utility.SetupAgentAndQueue(_queueName, _agentName);

            var tokenSource = new CancellationTokenSource();
            var taskList    = new List <Task>();

            taskList.Add(Task.Run(() => ReadQueue(context, tokenSource.Token)));
            taskList.Add(Task.Run(() => WriteQueue(context, agent.AgentId, tokenSource.Token)));

            await Task.Delay(TimeSpan.FromSeconds(20));

            tokenSource.Cancel();
            Task.WaitAll(taskList.ToArray());
        }
Exemple #12
0
        public async Task SimpleEnqueueWithLockTimeoutSuccessTestApi()
        {
            var context = _workContext.WithTag(_tag);

            AgentContractV1 agent = await _utility.SetupAgentAndQueue(_queueName, _agentName, lockValidForSec : 5);

            EnqueueMessageContractV1 message = _utility.CreateMessage(context, agent.AgentId, _queueName);

            await _client.Message.EnqueueMessage(context, message);

            await _utility.VerifyQueue(context, _queueName, 1, 0);

            MessageContractV1 readMessage = (await _client.Message.DequeueMessageWithLock(context, _queueName, agent, null)).Value;
            long saveMessageId            = readMessage.MessageId;

            _utility.VerifyMessage(message, readMessage, agent.AgentId, true);

            MessageContractV1 tempMessage = (await _client.Message.DequeueMessageWithLock(context, _queueName, agent, null)).Value;

            tempMessage.Should().BeNull();

            await Task.Delay(TimeSpan.FromSeconds(10));

            readMessage = (await _client.Message.DequeueMessageWithLock(context, _queueName, agent, null)).Value;
            _utility.VerifyMessage(message, readMessage, agent.AgentId, true);
            readMessage.MessageId.Should().Be(saveMessageId);

            var settleMessage = new SettleMessageContractV1
            {
                AgentId    = agent.AgentId,
                QueueName  = _queueName,
                SettleType = SettleType.Processed,
                MessageId  = readMessage.MessageId,
            };

            await _client.Message.SettleMessage(context, settleMessage);

            await _utility.VerifyQueue(context, _queueName, 0, 0);

            HistoryContractV1 history = (await _client.History.GetHistory(context, readMessage.MessageId)).Value;

            _utility.VerifyHistoryMessage(readMessage, history, _queueName, _agentName, retryCount: 2);
        }
Exemple #13
0
        public async Task <IActionResult> GetAgentId(string queueName, string agentName)
        {
            Verify.IsNotEmpty(nameof(queueName), queueName);
            Verify.IsNotEmpty(nameof(agentName), agentName);

            RequestContext requestContext = HttpContext.GetRequestContext();
            var            context        = requestContext.Context.WithTag(_tag);

            int agentId = await _message.GetAgentId(context, agentName);

            var result = new AgentContractV1
            {
                AgentId   = agentId,
                AgentName = agentName
            };

            return(new StandardActionResult(context)
                   .SetContent(result));
        }
        public async Task SimpleClearQueueHistoryTestApi()
        {
            var context = _workContext.WithTag(_tag);

            AgentContractV1 agent = await _utility.SetupAgentAndQueue(_queueName, _agentName);

            EnqueueMessageContractV1 message = _utility.CreateMessage(context, agent.AgentId, _queueName);

            RestResponse <EnqueuedContractV1> response = await _client.Message.EnqueueMessage(context, message);

            await _utility.VerifyQueue(context, _queueName, 1, 0);

            await _client.Management.ClearQueue(context, _queueName, true);

            await _utility.VerifyQueue(context, _queueName, 0, 0);

            HistoryContractV1 history = (await _client.History.GetHistory(context, response.Value.MessageId)).Value;

            history.Should().NotBeNull();
        }
Exemple #15
0
        public async Task SimpleEnqueueSuccessTestApi()
        {
            var context = _workContext.WithTag(_tag);

            AgentContractV1 agent = await _utility.SetupAgentAndQueue(_queueName, _agentName);

            EnqueueMessageContractV1 message = _utility.CreateMessage(context, agent.AgentId, _queueName);

            await _client.Message.EnqueueMessage(context, message);

            await _utility.VerifyQueue(context, _queueName, 1, 0);

            MessageContractV1 readMessage = (await _client.Message.DequeueMessageAndDelete(context, _queueName, null)).Value;

            _utility.VerifyMessage(message, readMessage, agent.AgentId, false);

            await _utility.VerifyQueue(context, _queueName, 0, 0);

            HistoryContractV1 history = (await _client.History.GetHistory(context, readMessage.MessageId)).Value;

            _utility.VerifyHistoryMessage(readMessage, history, _queueName, _agentName);
        }
        /// <summary>
        /// Dequeue message, no wait
        /// </summary>
        /// <param name="context">context</param>
        /// <param name="useSettle">use settle operations, true messages are locked and must be settled, false = read and delete (implicit)</param>
        /// <returns>message event or null for no message available</returns>
        public async Task <MessageEvent <T> > Dequeue(IWorkContext context, bool useSettle = true)
        {
            AgentContractV1 agent = await GetAgent(context);

            RestResponse <MessageContractV1> readMessage = null;

            await EnableQueue(context);

            if (!useSettle)
            {
                readMessage = await Client.Message.DequeueMessageAndDelete(context, QueueName);
            }
            else
            {
                readMessage = await Client.Message.DequeueMessageWithLock(context, QueueName, agent);
            }

            if (readMessage == null || readMessage.StatusCode == HttpStatusCode.NoContent)
            {
                return(null);
            }

            return(new MessageEvent <T>(readMessage.Value.Deserialize <T>(), readMessage.Value, agent, useSettle));
        }
        /// <summary>
        /// Dequeue a message if one is available and lock it for the agent
        /// </summary>
        /// <param name="context">context</param>
        /// <param name="queueName">queue name</param>
        /// <param name="waitFor">wait for message (should be greater than 30 seconds)</param>
        /// <param name="token">cancellation token (optional)</param>
        /// <returns>200 for message retrieved, 204 if no messages are available</returns>
        public async Task <RestResponse <MessageContractV1> > DequeueMessageWithLock(IWorkContext context, string queueName, AgentContractV1 agentContract, TimeSpan?waitFor = null, CancellationToken?token = null)
        {
            Verify.IsNotNull(nameof(context), context);
            Verify.IsNotEmpty(nameof(queueName), queueName);
            Verify.IsNotNull(nameof(agentContract), agentContract);
            context = context.WithTag(_tag);

            return(await CreateClient()
                   .AddPath(queueName)
                   .AddPath("message/head")
                   .AddQuery("agentId", agentContract.AgentId.ToString())
                   .AddQuery("waitMs", waitFor?.TotalMilliseconds.ToString())
                   .GetAsync(context)
                   .ToRestResponseAsync(context)
                   .EnsureSuccessStatusCodeAsync(context)
                   .GetContentAsync <MessageContractV1>(context));
        }
Exemple #18
0
        public async Task QueueSizeLimitTestApi()
        {
            const int messageSize = 10;
            var       context     = _workContext.WithTag(_tag);

            AgentContractV1 agent = await _utility.SetupAgentAndQueue(_queueName, _agentName, queueSize : 10);

            var messageList     = new List <EnqueueMessageContractV1>();
            var readMessageList = new List <MessageContractV1>();

            foreach (int index in Enumerable.Range(0, messageSize))
            {
                EnqueueMessageContractV1 message = _utility.CreateMessage(context, agent.AgentId, _queueName);
                messageList.Add(message);

                await _client.Message.EnqueueMessage(context, message);
            }

            await Verify.AssertExceptionAsync <RestConflictException>(async() =>
            {
                EnqueueMessageContractV1 message = _utility.CreateMessage(context, agent.AgentId, _queueName);
                await _client.Message.EnqueueMessage(context, message);
            });

            await _utility.VerifyQueue(context, _queueName, messageSize, 0);

            MessageContractV1 readMessage;

            foreach (int index in Enumerable.Range(0, messageSize))
            {
                readMessage = (await _client.Message.DequeueMessageWithLock(context, _queueName, agent, null)).Value;
                readMessage.Should().NotBeNull();
                readMessageList.Add(readMessage);
            }

            readMessage = (await _client.Message.DequeueMessageWithLock(context, _queueName, agent, null)).Value;
            readMessage.Should().BeNull();

            var zip = messageList
                      .OrderBy(x => x.ClientMessageId)
                      .Zip(readMessageList.OrderBy(x => x.ClientMessageId), (f, s) => new Tuple <EnqueueMessageContractV1, MessageContractV1>(f, s));

            foreach (var item in zip)
            {
                _utility.VerifyMessage(item.Item1, item.Item2, agent.AgentId, true);
            }

            foreach (var item in readMessageList)
            {
                var settleMessage = new SettleMessageContractV1
                {
                    AgentId    = agent.AgentId,
                    QueueName  = _queueName,
                    SettleType = SettleType.Processed,
                    MessageId  = item.MessageId,
                };

                await _client.Message.SettleMessage(context, settleMessage);
            }

            await _utility.VerifyQueue(context, _queueName, 0, 0);

            foreach (var item in readMessageList)
            {
                HistoryContractV1 history = (await _client.History.GetHistory(context, item.MessageId)).Value;
                _utility.VerifyHistoryMessage(item, history, _queueName, _agentName);
            }
        }
Exemple #19
0
 public MessageEvent(MessageContractV1 contract, CancellationToken token, AgentContractV1 agent)
 {
     Contract = contract;
     Token    = token;
     Agent    = agent;
 }
        private async Task RandomClient(IWorkContext context, MonitorReport report, int clientNumber, CancellationToken token)
        {
            string          agentName = $"{_options.AgentName}_Receive_{clientNumber}";
            AgentContractV1 agent     = (await _client.Message.GetAgentId(context, _options.QueueName, agentName)).Value;

            TimeSpan?waitFor = _options.NoWait ? (TimeSpan?)null : TimeSpan.FromSeconds(30);

            using (var monitor = new MonitorRate(report, agentName))
            {
                while (!token.IsCancellationRequested)
                {
                    try
                    {
                        RestResponse <MessageContractV1> readMessage;

                        if (_options.NoLock)
                        {
                            readMessage = await _client.Message.DequeueMessageAndDelete(context, _options.QueueName, waitFor, token);
                        }
                        else
                        {
                            readMessage = await _client.Message.DequeueMessageWithLock(context, _options.QueueName, agent, waitFor, token);
                        }

                        if (readMessage.StatusCode == HttpStatusCode.NoContent)
                        {
                            monitor.AddRetry();
                            await Utility.Delay(TimeSpan.FromMilliseconds(500), token);

                            continue;
                        }

                        WorkRequest workRequest = readMessage.Value.Deserialize <WorkRequest>();

                        lock (_lock)
                        {
                            if (workRequest.MessageCount > _highMessageCount)
                            {
                                _highMessageCount = workRequest.MessageCount;
                            }
                        }

                        await Utility.Delay(_options.Delay, token);

                        if (!_options.NoLock)
                        {
                            var settleMessage = new SettleMessageContractV1
                            {
                                AgentId    = agent.AgentId,
                                QueueName  = _options.QueueName,
                                SettleType = SettleType.Processed,
                                MessageId  = readMessage.Value.MessageId,
                            };

                            await _client.Message.SettleMessage(context, settleMessage);
                        }

                        monitor.IncrementRead();
                    }
                    catch (Exception ex)
                    {
                        monitor.IncrementError(ex.ToString());
                    }
                }
            }
        }