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
                        }
                    });
                }
            }
        }
Пример #3
0
        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
            });
        }
Пример #4
0
        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,
                        });
                    }
                }
            }
        }