public async Task ReDeliverStuckMessage(Data.DataContext _context) { DateTime DeservedTimeForError = DateTime.Now.AddMinutes(-_config.ReDelivery.MaxTotalMinuteForError); DateTime DeservedTimeForInProducer = DateTime.Now.AddMinutes(-_config.ReDelivery.MaxTotalMinuteForInProducer); List <Message> stuckMessages = await _context.Messages.Where(m => (m.Status == MessageStatuses.ERROR && m.UpdatedAt <= DeservedTimeForError) || (m.Status == MessageStatuses.INPRODUCER && m.UpdatedAt <= DeservedTimeForInProducer)) .ToListAsync(); foreach (Message message in stuckMessages) { // stuck message, log it if (message.ReDeliveryTimes >= _config.ReDelivery.MaxRetryTimes) { using var transaction = _context.Database.BeginTransaction(); StuckMessage stuckMessage = _mapper.Map <StuckMessage>(message); stuckMessage.StuckReason = MessageStuckReasons.MAX_RETRY_EXCEED; await _context.StuckMessages.AddAsync(stuckMessage); _context.Messages.Remove(message); await _context.SaveChangesAsync(); transaction.Commit(); } else { await _queueService.ReScheduleMessage(message); } } }
private async Task HandleBasicNack(ulong DeliveryTag, bool IsMultiple) { using (var scope = _provider.CreateScope()) { DataContext _context = scope.ServiceProvider.GetRequiredService <DataContext>(); IMapper _mapper = scope.ServiceProvider.GetRequiredService <IMapper>(); List <Guid> MessageIds = GetOutstandingConfirm(DeliveryTag, IsMultiple); List <Message> messages = await _context.Messages.Where(m => MessageIds.Contains(m.Id)).ToListAsync(); List <StuckMessage> stuckMessages = new(); foreach (Message msg in messages) { // prepare stuck message record StuckMessage stuckMessage = _mapper.Map <StuckMessage>(msg); stuckMessage.StuckReason = MessageStuckReasons.QUEUE_NACK; stuckMessages.Add(stuckMessage); msg.Status = MessageStatuses.LOGGED; msg.UpdatedAt = DateTime.Now; } using (var transaction = _context.Database.BeginTransaction()) { if (messages.Count >= _config.DBConfig.DeservedBulk) { await _context.BulkDeleteAsync(messages, options => options.PropertiesToInclude = new List <string>() { nameof(Message.Status), nameof(Message.UpdatedAt) }); } else { _context.Messages.RemoveRange(messages); } if (stuckMessages.Count >= _config.DBConfig.DeservedBulk) { await _context.BulkInsertAsync(stuckMessages); } else { await _context.StuckMessages.AddRangeAsync(stuckMessages); } await _context.SaveChangesAsync(); transaction.Commit(); } } RemoveOutstandingConfirm(DeliveryTag, IsMultiple); }