refactor(unitFilterService): Этапы фильтрации вынесены в отдельные классы
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using System.Diagnostics;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using PARR.Core.Repositories.Interfaces;
|
||||
using PARR.Core.Repositories.Interfaces.Job;
|
||||
@@ -56,6 +57,7 @@ internal class GroupedTemplateSynchronizer : ITemplateSynchronizer
|
||||
|
||||
public async Task SyncTemplatesForJobGroupAsync(Guid jobGroupId, HistoryInitiator initiator)
|
||||
{
|
||||
var totalSw = Stopwatch.StartNew();
|
||||
logger.LogInformation("Начало синхронизации шаблонов для JobGroup {JobGroupId}", jobGroupId);
|
||||
|
||||
// === Проверка: уже запущена? ===
|
||||
@@ -82,7 +84,8 @@ internal class GroupedTemplateSynchronizer : ITemplateSynchronizer
|
||||
|
||||
try
|
||||
{
|
||||
// 1. Загрузка JobGroup и связанных Job'ов
|
||||
// === ЭТАП 1: Загрузка JobGroup ===
|
||||
var stageSw = Stopwatch.StartNew();
|
||||
var jobGroup = await jobGroupService.Get()
|
||||
.AsNoTracking()
|
||||
.AsSingleQuery()
|
||||
@@ -105,8 +108,11 @@ internal class GroupedTemplateSynchronizer : ITemplateSynchronizer
|
||||
}
|
||||
|
||||
var jobsInGroup = jobGroup.Jobs.ToList();
|
||||
stageSw.Stop();
|
||||
logger.LogDebug("[Perf] JobGroup {JobGroupId} | Этап: Загрузка JobGroup | Время: {Ms} мс | Jobs: {Count}",
|
||||
jobGroupId, stageSw.ElapsedMilliseconds, jobsInGroup.Count);
|
||||
|
||||
// 2. Поиск Job с максимальным MaxValueRelationships
|
||||
// === Поиск эталонного Job ===
|
||||
var maxJob = jobsInGroup
|
||||
.Where(j => j.MaxValueRelationships.HasValue)
|
||||
.OrderByDescending(j => j.MaxValueRelationships)
|
||||
@@ -121,9 +127,13 @@ internal class GroupedTemplateSynchronizer : ITemplateSynchronizer
|
||||
|
||||
logger.LogDebug("Используется Job {JobId} с максимальным MaxValueRelationships ({MaxValue}).", maxJob.Id, maxJob.MaxValueRelationships);
|
||||
|
||||
// 3. Получение отфильтрованных юнитов через UnitFilterService
|
||||
logger.LogDebug("Получение отфильтрованных юнитов через UnitFilterService для Job {JobId}.", maxJob.Id);
|
||||
// === ЭТАП 2: Фильтрация юнитов ===
|
||||
stageSw.Restart();
|
||||
var unitFilterResults = await unitFilterService.GetUnitsByJobFilterAsync(maxJob.Id);
|
||||
stageSw.Stop();
|
||||
var filterCount = unitFilterResults?.Count() ?? 0;
|
||||
logger.LogDebug("[Perf] JobGroup {JobGroupId} | Этап: Фильтрация юнитов | Время: {Ms} мс | Результат: {Count}",
|
||||
jobGroupId, stageSw.ElapsedMilliseconds, filterCount);
|
||||
|
||||
if (unitFilterResults == null || !unitFilterResults.Any())
|
||||
{
|
||||
@@ -133,21 +143,26 @@ internal class GroupedTemplateSynchronizer : ITemplateSynchronizer
|
||||
return;
|
||||
}
|
||||
|
||||
// 4. Применение специфичных правил фильтрации для групповых шаблонов
|
||||
logger.LogDebug("Применение специфичных правил фильтрации для групповых шаблонов.");
|
||||
// === ЭТАП 3: Групповая фильтрация ===
|
||||
stageSw.Restart();
|
||||
var finalFilteredUnits = await groupedTemplateUnitFilter.FilterAsync(unitFilterResults, jobGroup);
|
||||
stageSw.Stop();
|
||||
logger.LogDebug("[Perf] JobGroup {JobGroupId} | Этап: Групповая фильтрация | Время: {Ms} мс | Результат: {Count}",
|
||||
jobGroupId, stageSw.ElapsedMilliseconds, finalFilteredUnits.Count);
|
||||
|
||||
if (!finalFilteredUnits.Any())
|
||||
{
|
||||
logger.LogInformation("После применения правил фильтрации в JobGroup {JobGroupId} не осталось юнитов.", jobGroupId);
|
||||
await UpdateMatchingStatusAsync(jobGroupId, "Нет юнитов после фильтрации");
|
||||
await matchingStatusService.DeleteMatchingStatusAsync(jobGroupId, SyncTaskEntityTypeEnum.JobGroup);
|
||||
return;
|
||||
await matchingStatusService.DeleteMatchingStatusAsync(jobGroupId, SyncTaskEntityTypeEnum.JobGroup); return;
|
||||
}
|
||||
|
||||
// 5. Разрешение конфликтов связей и построение первичного маппинга
|
||||
logger.LogDebug("Разрешение конфликтов связей и построение первичного маппинга.");
|
||||
// === ЭТАП 4: Разрешение конфликтов ===
|
||||
stageSw.Restart();
|
||||
var initialReverseMapping = await unitInTemplateConflictMapper.BuildMappingAsync(finalFilteredUnits, maxJob);
|
||||
stageSw.Stop();
|
||||
logger.LogDebug("[Perf] JobGroup {JobGroupId} | Этап: Разрешение конфликтов | Время: {Ms} мс | Связей: {Count}",
|
||||
jobGroupId, stageSw.ElapsedMilliseconds, initialReverseMapping.Count);
|
||||
|
||||
if (!initialReverseMapping.Any())
|
||||
{
|
||||
@@ -156,9 +171,12 @@ internal class GroupedTemplateSynchronizer : ITemplateSynchronizer
|
||||
return;
|
||||
}
|
||||
|
||||
// 6. Построение структуры групп (трансформация, внутренняя группировка, разбиение)
|
||||
logger.LogDebug("Построение структуры групп для шаблонов.");
|
||||
// === ЭТАП 5: Построение структуры групп ===
|
||||
stageSw.Restart();
|
||||
var templateGroups = await groupedTemplateBuilder.BuildAsync(initialReverseMapping, jobGroup, maxJob);
|
||||
stageSw.Stop();
|
||||
logger.LogDebug("[Perf] JobGroup {JobGroupId} | Этап: Построение групп | Время: {Ms} мс | Групп: {Count}",
|
||||
jobGroupId, stageSw.ElapsedMilliseconds, templateGroups.Count);
|
||||
|
||||
if (!templateGroups.Any())
|
||||
{
|
||||
@@ -167,25 +185,37 @@ internal class GroupedTemplateSynchronizer : ITemplateSynchronizer
|
||||
return;
|
||||
}
|
||||
|
||||
// 7. Обработка групп: сравнение, обновление, создание, отправка MQ
|
||||
logger.LogDebug("Обработка групп шаблонов: сравнение, обновление и создание.");
|
||||
// === ЭТАП 6: Обработка групп (сравнение, обновление, MQ) ===
|
||||
stageSw.Restart();
|
||||
var expectedTemplateKeys = await groupedTemplateProcessor.ProcessAsync(
|
||||
templateGroups,
|
||||
jobsInGroup,
|
||||
maxJob,
|
||||
initiator);
|
||||
stageSw.Stop();
|
||||
logger.LogDebug("[Perf] JobGroup {JobGroupId} | Этап: Обработка групп | Время: {Ms} мс | Ключей: {Count}",
|
||||
jobGroupId, stageSw.ElapsedMilliseconds, expectedTemplateKeys.Count);
|
||||
|
||||
// 8. Деактивация лишних шаблонов
|
||||
// === ЭТАП 7: Деактивация лишних шаблонов ===
|
||||
stageSw.Restart();
|
||||
await DeactivateUnusedTemplatesAsync(expectedTemplateKeys, jobGroupId, jobsInGroup, initiator);
|
||||
stageSw.Stop();
|
||||
logger.LogDebug("[Perf] JobGroup {JobGroupId} | Этап: Деактивация | Время: {Ms} мс",
|
||||
jobGroupId, stageSw.ElapsedMilliseconds);
|
||||
|
||||
// === ИТОГО === totalSw.Stop();
|
||||
logger.LogInformation(
|
||||
"[Perf] JobGroup {JobGroupId} | ИТОГО: {TotalMs} мс",
|
||||
jobGroupId, totalSw.ElapsedMilliseconds);
|
||||
|
||||
// 9. Успешное завершение
|
||||
await UpdateMatchingStatusAsync(jobGroupId, "Синхронизация завершена успешно");
|
||||
await matchingStatusService.DeleteMatchingStatusAsync(jobGroupId, SyncTaskEntityTypeEnum.JobGroup);
|
||||
logger.LogInformation("Синхронизация шаблонов завершена для JobGroup {JobGroupId}.", jobGroupId);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
logger.LogError(ex, "Ошибка при синхронизации JobGroup {JobGroupId}", jobGroupId);
|
||||
totalSw.Stop();
|
||||
logger.LogError(ex, "Ошибка при синхронизации JobGroup {JobGroupId} через {ElapsedMs} мс", jobGroupId, totalSw.ElapsedMilliseconds);
|
||||
await UpdateMatchingStatusAsync(jobGroupId, $"Ошибка: {ex.Message}");
|
||||
throw;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user