public async Task ShouldLogError_IfProcessMessageIsUnsuccessful() { //Arrange var service = SetupService(); _processService.ProccessMessageAsync(Arg.Any <RingbaUOW>()) .Returns(Task.FromResult(new ActionResult { IsSuccessfull = false })); //Act await service.ProcessMessageAsync(new MessageWrapper <RingbaUOW> { Body = new RingbaUOW() }, new ConcurrentBag <UpdateBatchRequest>(), new ConcurrentBag <string>()); //Assert Assert.Equal(1, service.ReceivedCalls().Count(c => c.GetMethodInfo().Name == "LogErrorAsync")); }
public void DoWork() { // Pseudo-code to illustrate a naive implementation. Provide an optimal implementation. while (true) { var batch = _queService.GetMessagesFromQueAsync <RingbaUOW>(10, 30, 30).Result; foreach (var message in batch.Messages) { var result = _processService.ProccessMessageAsync(message.Body).Result; _queService.UpdateMessagesAsync(new UpdateBatchRequest[] { new UpdateBatchRequest { Id = message.Id, MessageCompleted = result.IsSuccessfull } }); } } }
private async Task <UpdateBatchRequest> ProcessSingleMessage(MessageWrapper <RingbaUOW> message, CancellationToken token) { await _logService.LogInfoAsync(_logId, $"Processing message: {message.Id} started."); var uow = message.Body; try { token.ThrowIfCancellationRequested(); if (!await _uowStatusService.TrySetInProcessing(uow.UOWId)) { await _logService.LogInfoAsync(_logId, $"Unable to start processing message: {message.Id}, UOWId: {uow.UOWId}."); return(null); } if (await _uowStatusService.HasExpiredAge(uow.UOWId, uow.CreationEPOCH, uow.MaxAgeInSeconds) || await _uowStatusService.HasExpiredRetries(uow.UOWId, uow.MaxNumberOfRetries)) { await _logService.LogInfoAsync(_logId, $"Expiry reached for message : {message.Id}, UOWId: {uow.UOWId}. Returning message as completed."); await _uowStatusService.ClearStatusMetadata(uow.UOWId); return(new UpdateBatchRequest { Id = message.Id, MessageCompleted = true }); } var sw = Stopwatch.StartNew(); ActionResult result = await _processService.ProccessMessageAsync(message.Body); sw.Stop(); await _logService.LogInfoAsync(_logId, $"Processing message: {message.Id}, UOWId: {uow.UOWId} completed with message status: {result.GetStatusInfo()}, took: {sw.ElapsedMilliseconds} ms."); if (result.IsSuccessfull) { await _uowStatusService.ClearStatusMetadata(uow.UOWId); } else { await _uowStatusService.ResetInProcessing(uow.UOWId); } return(new UpdateBatchRequest { Id = message.Id, MessageCompleted = result.IsSuccessfull }); } catch (OperationCanceledException) { await _logService.LogWarningAsync(_logId, $"Processing of message: {message.Id}, UOWId: {uow.UOWId} has been cancelled."); } catch (Exception ex) //TODO: Change implementation to only catch exceptions expected from ProcessMessageAsync { await _logService.LogExceptionAsync(_logId, ex, $"Processing message by id: {message.Id}, UOWId: {uow.UOWId} failed."); } await _uowStatusService.ResetInProcessing(uow.UOWId); return(new UpdateBatchRequest { Id = message.Id, MessageCompleted = false }); }
public virtual async Task ProcessMessageAsync(MessageWrapper <RingbaUOW> message, ConcurrentBag <UpdateBatchRequest> updateBatchRequests, ConcurrentBag <string> successfulUowIds) { await LogInfoAsync( $"ImplementMeService.ProcessMessageAsync starting for UOWId {message.Body.UOWId} @ {Environment.MachineName}", "PreProcessMessage", new { UOWId = message.Body.UOWId, }); using (var lockItem = await _centralizedLock.TryAcquireAsync($"{LockKeyPrefix}{message.Body.UOWId}")) { if (lockItem.IsLocked) { await LogInfoAsync( $"ImplementMeService.ProcessMessageAsync successfully acquired lock for UOWId {message.Body.UOWId} @ {Environment.MachineName}", "AcquireLock", new { UOWId = message.Body.UOWId, }); ActionResult result = null; Exception exception = null; try { result = await _processService.ProccessMessageAsync(message.Body); if (!result.IsSuccessfull) { await LogErrorAsync(result.ErrorCode, result.ErrorMessage, "ProcessMessage"); } else { await LogInfoAsync( $"ImplementMeService.ProcessMessageAsync successfully processed UOWId {message.Body.UOWId} @ {Environment.MachineName}", "ProcessMessage", new { UOWId = message.Body.UOWId, }); } } catch (Exception e) { await _logservice.LogAsync(Guid.NewGuid().ToString(), e.Message, LOG_LEVEL.EXCEPTION, new { UOWId = message.Body.UOWId, MachineName = Environment.MachineName, ServiceName = "ImplementMeService", ActionName = "ProcessMessage", ExceptionMessage = e.Message, }); exception = e; } finally { bool messageCompleted; if (result != null && !result.IsSuccessfull || exception != null) { await _logservice.LogAsync(Guid.NewGuid().ToString(), $"ImplementMeService.ProcessMessageAsync did not process UOWId {message.Body.UOWId} successfully, evaluating requeue @ {Environment.MachineName}", LOG_LEVEL.WARNING, new { UOWId = message.Body.UOWId, MachineName = Environment.MachineName, ServiceName = "ImplementMeService", ActionName = "ProcessMessage", }); messageCompleted = !await ShouldRequeueAsync(message.Body.UOWId, message.Body.CreationEPOCH, message.Body.MaxAgeInSeconds, message.Body.MaxNumberOfRetries); } else { messageCompleted = true; } if (messageCompleted) { successfulUowIds.Add(message.Body.UOWId); } await LogInfoAsync( $"ImplementMeService.ProcessMessageAsync queued UOWId {message.Body.UOWId} message update @ {Environment.MachineName}", "EnqueueMessageUpdate", new { UOWId = message.Body.UOWId, }); updateBatchRequests.Add(new UpdateBatchRequest { Id = message.Id, MessageCompleted = messageCompleted, }); } } } }