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(); } } } }
public MessageEvent(T message, MessageContractV1 contract, AgentContractV1 agent, bool useSettle) { Message = message; Contract = contract; Agent = agent; UseSettle = useSettle; }
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); }
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()); }
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); }
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(); }
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)); }
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); } }
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()); } } } }