feat(dal,core): Рефакторинг методов и логики выдачи заданий роботом при переименовании шаблонов
This commit is contained in:
@@ -48,13 +48,13 @@ namespace PARR.Core.Services.RobotTask.Implementations
|
||||
ITemplateRenamePendingRepository templateRenamePendingRepository
|
||||
)
|
||||
{
|
||||
this._logger = logger;
|
||||
this._robotConfigurationRepository = robotConfigurationRepository;
|
||||
this._settingsFromDb = settingsFromDb;
|
||||
this._robotHistoryRepository = robotHistoryRepository;
|
||||
this._mapper = mapper;
|
||||
this._shortcodesService = shortcodesService;
|
||||
this._nextRunService = nextRunService;
|
||||
_logger = logger;
|
||||
_robotConfigurationRepository = robotConfigurationRepository;
|
||||
_settingsFromDb = settingsFromDb;
|
||||
_robotHistoryRepository = robotHistoryRepository;
|
||||
_mapper = mapper;
|
||||
_shortcodesService = shortcodesService;
|
||||
_nextRunService = nextRunService;
|
||||
_templateRenamePendingRepository = templateRenamePendingRepository;
|
||||
}
|
||||
|
||||
@@ -264,17 +264,18 @@ namespace PARR.Core.Services.RobotTask.Implementations
|
||||
|
||||
|
||||
// Ищем есть ли связанные шаблоны с таким имененм на переименование
|
||||
var taskTemplateNames = tasks.Select(t => t.TemplateName);
|
||||
var taskTemplateNames = tasks.Select(t => t.TemplateName).Distinct().ToList();
|
||||
// Ищем записи в таблице переименований, где OldName совпадает с именами наших новых задач
|
||||
var templatesToRename = await _templateRenamePendingRepository.Get().AsNoTracking()
|
||||
.Where(t => taskTemplateNames.Contains(t.OldName))
|
||||
.ToListAsync();
|
||||
|
||||
_logger.LogDebug("Шаблонов для переименования в текущем задании: {Count} шт.", templatesToRename.Count);
|
||||
_logger.LogDebug("Найдено шаблонов в процессе переименования для текущих задач: {Count} шт.", templatesToRename.Count);
|
||||
|
||||
if (templatesToRename.Count == 0)
|
||||
return tasks;
|
||||
|
||||
// Ищем связанные переименованные шаблоны по ИД, смотрим можем ли взять их в работу
|
||||
// Ищем конфигурации роботов для СТАРЫХ шаблонов (которые переименовываются) по ИД, смотрим, можем ли взять их в работу
|
||||
var renameTemplateIds = templatesToRename.Select(t => t.TemplateId).ToList();
|
||||
var renameTasks = await _robotConfigurationRepository.Get()
|
||||
.AsNoTracking()
|
||||
@@ -286,63 +287,93 @@ namespace PARR.Core.Services.RobotTask.Implementations
|
||||
&& t.TaskStatusCode == (int)TaskStatusEnum.Updating
|
||||
).ToListAsync();
|
||||
|
||||
// Ищем связанные задания которые в ошибке, и ставим целевому шаблону задание в ошибку
|
||||
var errorTasks = renameTasks.Where(t => t.RobotStatusCode == (int)RobotStatusEnum.Error && t.AttemptsNumber >= _settingsFromDb.RobotAttemptsNumber).ToList();
|
||||
// --- Блок обработки ошибок ---
|
||||
|
||||
// Если старый шаблон в ошибке и лимит попыток исчерпан, ставим ошибку и новому шаблону
|
||||
var errorTasks = renameTasks
|
||||
.Where(t =>
|
||||
t.RobotStatusCode == (int)RobotStatusEnum.Error
|
||||
&& t.AttemptsNumber >= _settingsFromDb.RobotAttemptsNumber
|
||||
).ToList();
|
||||
|
||||
var tasksToSetErrorStatus = new List<Guid>();
|
||||
if (errorTasks.Count > 0)
|
||||
{
|
||||
_logger.LogDebug("Найдено связанных заданий на переименование с ошибками: {ErrorCount}. Будем целевым шаблонам тоже ставить статус ошибки.", errorTasks.Count);
|
||||
_logger.LogDebug("Найдено старых заданий на переименование с ошибками: {ErrorCount}. Ставим ошибку целевым (новым) заданиям.", errorTasks.Count);
|
||||
|
||||
var errorTemplateNames = errorTasks.Select(t => t.Template!.Name).ToList();
|
||||
var errorTemplateNames = errorTasks.Select(t => t.Template!.Name).ToHashSet();
|
||||
// Берем целевые таски, находим в них задания которым надо поставить ошибку
|
||||
tasksToSetErrorStatus = tasks.Where(t => errorTemplateNames.Contains(t.TemplateName)).Select(t => t.TaskId).ToList();
|
||||
tasksToSetErrorStatus = tasks
|
||||
.Where(t => errorTemplateNames.Contains(t.TemplateName))
|
||||
.Select(t => t.TaskId)
|
||||
.ToList();
|
||||
|
||||
// Устанавливаем ошибку целевым + пишем комментарий от робота + нажимаем комит
|
||||
var logMessage = "[RobotTaskService] Установлен статус ошибки, так как не переименован связанный шаблон";
|
||||
await SetErrorStatusAsync(tasksToSetErrorStatus, logMessage);
|
||||
if (tasksToSetErrorStatus.Count > 0)
|
||||
{
|
||||
// Устанавливаем ошибку целевым + пишем комментарий от робота + нажимаем комит
|
||||
var logMessage = "[RobotTaskService] Установлен статус ошибки, так как не переименован связанный шаблон";
|
||||
await SetErrorStatusAsync(tasksToSetErrorStatus, logMessage);
|
||||
}
|
||||
}
|
||||
|
||||
// --- Блок подмены задач ---
|
||||
|
||||
var endDate = DateTimeOffset.UtcNow.Add(-_settingsFromDb.RobotWaitTime);
|
||||
// Смотрим статусы роботов, можно взять в работу, только если (RobotStatus == Wait) или (InpRogress но которые еще не просрочены)
|
||||
var allowedTasks = renameTasks.Where(t =>
|
||||
|
||||
// Фильтруем старые задачи, которые МОЖНО взять в работу. Смотрим статусы роботов, можно взять в работу, только если (RobotStatus == Wait) или (InpRogress но которые еще не просрочены)
|
||||
var allowedRenameTasks = renameTasks.Where(t =>
|
||||
t.RobotStatusCode == (int)RobotStatusEnum.Wait
|
||||
|| (t.RobotStatusCode == (int)RobotStatusEnum.InProgress && t.AttemptsNumber < _settingsFromDb.RobotAttemptsNumber && t.LastRobotStatusUpdated < endDate)
|
||||
);
|
||||
|| (t.RobotStatusCode == (int)RobotStatusEnum.InProgress
|
||||
&& t.AttemptsNumber < _settingsFromDb.RobotAttemptsNumber
|
||||
&& t.LastRobotStatusUpdated < endDate)
|
||||
).ToList();
|
||||
|
||||
// Формируем список заданий
|
||||
// Словарь для поиска подменной задачи по имени шаблона.
|
||||
// GroupBy + First на случай, если в бд есть дубликаты, но такого быть не может
|
||||
var renameTasksToDictionary = allowedRenameTasks
|
||||
.GroupBy(t => t.Template!.Name)
|
||||
.ToDictionary(
|
||||
t => t.Key,
|
||||
t => new RobotTaskDetails(t.First().Id, t.First().Template!.Name, t.First().Template!.NextRun)
|
||||
);
|
||||
|
||||
var originalCount = tasks.Count; // Запоминаем сколько было изначально
|
||||
var errorTaskIdsSet = tasksToSetErrorStatus.ToHashSet();
|
||||
|
||||
// Из исходных тасков удалить те которым установлен статус ошибки
|
||||
var filteredOriginalTasks = tasks.Where(t => !tasksToSetErrorStatus.Contains(t.TaskId)).ToList();
|
||||
var errorCount = tasksToSetErrorStatus.Count; // Столько ушло в ошибку
|
||||
// Создаем итоговый список
|
||||
var finalTasks = new List<RobotTaskDetails>(tasks.Count);
|
||||
int replacedCount = 0;
|
||||
int errorCount = errorTaskIdsSet.Count;
|
||||
|
||||
// Определяем, какие имена шаблонов мы БУДЕМ подменять на задачи переименования
|
||||
var allowedRenameTemplateNames = allowedTasks.Select(t => t.Template!.Name).ToList();
|
||||
// Проходим по ИСХОДНОМУ списку, чтобы сохранить его порядок сортировки
|
||||
foreach (var task in tasks)
|
||||
{
|
||||
// Если задаче нужно поставить ошибку, просто пропускаем ее (она не попадет в итоговый список)
|
||||
if (errorTaskIdsSet.Contains(task.TaskId))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// Из исходных удаляем те, которые мы сейчас заменим (подменим)
|
||||
var resultsTasks = filteredOriginalTasks.Where(t => !allowedRenameTemplateNames.Contains(t.TemplateName)).ToList();
|
||||
// Если для этого имени шаблона есть разрешенная задача на переименование - вставляем ее на место текущей
|
||||
if (renameTasksToDictionary.TryGetValue(task.TemplateName, out var renameTask))
|
||||
{
|
||||
finalTasks.Add(renameTask);
|
||||
replacedCount++;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Иначе оставляем исходную задачу на месте
|
||||
finalTasks.Add(task);
|
||||
}
|
||||
}
|
||||
|
||||
// Считаем сколько именно задач мы ВЫКИНУЛИ из исходного списка ради подмены
|
||||
var replacedCount = filteredOriginalTasks.Count - resultsTasks.Count;
|
||||
|
||||
// В исходные добавляем подменные таски для переименования (мапим их в RobotTaskDetails)
|
||||
var mappedRenameTasks = allowedTasks.Select(t => new RobotTaskDetails(t.Id, t.Template!.Name, t.Template.NextRun)).ToList();
|
||||
resultsTasks.AddRange(mappedRenameTasks);
|
||||
|
||||
var injectedCount = mappedRenameTasks.Count; // Столько задач переименования добавили взамен
|
||||
|
||||
// Логируем итоговую статистику трансформации пула задач
|
||||
// TODO: Позже этот лог можно понизить до Debug!!!
|
||||
_logger.LogInformation(
|
||||
"Трансформация пула задач завершена. Исходных: {OriginalCount} шт. " +
|
||||
"Отклонено (ошибка): {ErrorCount} шт. Удалено обычных для подмены: {ReplacedCount} шт. " +
|
||||
"Внедрено задач переименования: {InjectedCount} шт. Итого к выдаче: {FinalCount} шт.",
|
||||
originalCount, errorCount, replacedCount, injectedCount, resultsTasks.Count);
|
||||
"Трансформация пула задач (Rename). Исходных: {OriginalCount}. Отклонено (Error): {ErrorCount}. " +
|
||||
"Заменено на старые: {ReplacedCount}. Итого к выдаче: {FinalCount}",
|
||||
tasks.Count, errorCount, replacedCount, finalTasks.Count
|
||||
);
|
||||
|
||||
// Затем отсортируем по NextRun, чтоб ближайшие были выше
|
||||
return resultsTasks.OrderBy(t => t.NextRun).ToList();
|
||||
// Возвращаем без дополнительной сортировки по NextRun. Порядок сохранен начального списка
|
||||
return finalTasks;
|
||||
}
|
||||
|
||||
|
||||
@@ -353,9 +384,13 @@ namespace PARR.Core.Services.RobotTask.Implementations
|
||||
/// <returns></returns>
|
||||
private async Task SetErrorStatusAsync(List<Guid> taskIds, string logMessage)
|
||||
{
|
||||
if (taskIds == null || taskIds.Count == 0)
|
||||
return;
|
||||
|
||||
var tasks = await _robotConfigurationRepository.Get()
|
||||
.Include(t => t.Template)
|
||||
.Where(t => taskIds.Contains(t.Id)).ToListAsync();
|
||||
.Where(t => taskIds.Contains(t.Id))
|
||||
.ToListAsync();
|
||||
|
||||
if (tasks.Count == 0)
|
||||
return;
|
||||
@@ -380,16 +415,19 @@ namespace PARR.Core.Services.RobotTask.Implementations
|
||||
|
||||
await _robotHistoryRepository.CreateAsync(history);
|
||||
|
||||
_logger.LogInformation("Для целевого задания {TaskId}, по переименованию шаблона в {TemplateName}, установлен статус ошибки, так как связанное задание со старым шаблоном со статусом ошибка.", task.Id, task.Template!.Name);
|
||||
_logger.LogInformation("Для целевого задания {TaskId} (шаблон '{TemplateName}') установлен статус ошибки, " +
|
||||
"так как связанное задание со старым шаблоном не было успешно выполнено.",
|
||||
task.Id, task.Template!.Name);
|
||||
}
|
||||
|
||||
if (await _robotHistoryRepository.CommitAsync())
|
||||
{
|
||||
_logger.LogDebug("Установлен статус Ошибка, для заданий {TaskCount} шт.", tasks.Count);
|
||||
_logger.LogDebug("Установлен статус 'Ошибка', для заданий {TaskCount} шт.", tasks.Count);
|
||||
}
|
||||
else
|
||||
{
|
||||
_logger.LogError("Ошибка при установке статуса задания Ошибка, для заданий {TaskCount} шт.", tasks.Count);
|
||||
_logger.LogError("Ошибка при установке статуса задания 'Ошибка', для заданий {TaskCount} шт. Транзакция отменена", tasks.Count);
|
||||
throw new DbErrorException("Не удалось сохранить изменения статусов заданий при обработке переименования шаблона.");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -531,19 +569,19 @@ namespace PARR.Core.Services.RobotTask.Implementations
|
||||
|
||||
if (!nextRun.HasValue)
|
||||
{
|
||||
_logger.LogError("При обновлении nextRun для шаблона {templateId}, расчитанный nextRun=null, ошибка в расчетах.", template.Id);
|
||||
_logger.LogError("При обновлении nextRun для шаблона {TemplateId}, расчитанный nextRun=null, ошибка в расчетах.", template.Id);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (nextRun.Value < DateTimeOffset.UtcNow)
|
||||
{
|
||||
_logger.LogError("При обновлении nextRun для шаблона {templateId}, расчитанный nextRun<Now [{nextRun}<{now}], ошибка в расчетах.", template.Id, nextRun.Value, DateTimeOffset.UtcNow);
|
||||
_logger.LogError("При обновлении nextRun для шаблона {TemplateId}, расчитанный nextRun<Now [{NextRun}<{Now}], ошибка в расчетах.", template.Id, nextRun.Value, DateTimeOffset.UtcNow);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (nextRun != template.NextRun)
|
||||
{
|
||||
_logger.LogDebug($"Для шаблона id {template.Id} обновляю nextRun, новое значение {nextRun}, старое значение {template.NextRun}");
|
||||
_logger.LogDebug("Для шаблона {TemplateId} обновляю nextRun. Новое: {NewNextRun}, старое: {OldNextRun}", template.Id, nextRun, template.NextRun);
|
||||
|
||||
template.LastRun = template.NextRun;
|
||||
template.NextRun = nextRun.Value;
|
||||
|
||||
Reference in New Issue
Block a user