feat(templateMatcher):
- добавлен режим DryRun - изменен подход к фильтрации шаблонов по рабочей группе - перенесено из этапа основной фильтрации в этап посторение подргупп/шаблонов - при использовании тегов альтернативных рабочих групп фильтрация по списку пропускается
This commit is contained in:
@@ -76,12 +76,12 @@ internal class SimpleTemplateSynchronizer : ITemplateSynchronizer
|
||||
this._unitRepository = unitRepository;
|
||||
}
|
||||
|
||||
public async Task SyncTemplatesForJobAsync(Guid jobId, HistoryInitiator initiator)
|
||||
public async Task SyncTemplatesForJobAsync(Guid jobId, HistoryInitiator initiator, bool dryRun = false)
|
||||
{
|
||||
if (jobId == _settingsFromDb.JobIdForUnusedTemplates)
|
||||
{
|
||||
_logger.LogInformation("Обработка синхронизации для Job неиспользуемых шаблонов '{JobId}'", jobId);
|
||||
await SyncUnusedTemplatesAsync(jobId, initiator);
|
||||
await SyncUnusedTemplatesAsync(jobId, initiator, dryRun);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -120,38 +120,95 @@ internal class SimpleTemplateSynchronizer : ITemplateSynchronizer
|
||||
context.JobName, jobId, stage.StageName, stageSw.ElapsedMilliseconds);
|
||||
}
|
||||
|
||||
foreach (var stage in _writeStages)
|
||||
// Подробный отчёт по результатам read-этапов
|
||||
PrintDryRunReport(context);
|
||||
|
||||
if (!dryRun)
|
||||
{
|
||||
var stageSw = Stopwatch.StartNew();
|
||||
await stage.ExecuteAsync(context);
|
||||
stageSw.Stop();
|
||||
_logger.LogDebug("[Perf] Job '{JobName}' ({JobId}) | Этап: {Stage} | Время: {Ms} мс",
|
||||
context.JobName, jobId, stage.StageName, stageSw.ElapsedMilliseconds);
|
||||
foreach (var stage in _writeStages)
|
||||
{
|
||||
var stageSw = Stopwatch.StartNew();
|
||||
await stage.ExecuteAsync(context);
|
||||
stageSw.Stop();
|
||||
_logger.LogDebug("[Perf] Job '{JobName}' ({JobId}) | Этап: {Stage} | Время: {Ms} мс",
|
||||
context.JobName, jobId, stage.StageName, stageSw.ElapsedMilliseconds);
|
||||
}
|
||||
|
||||
await UpdateMatchingStatusAsync(jobId, "Синхронизация завершена успешно");
|
||||
await _matchingStatusService.DeleteMatchingStatusAsync(jobId, SyncTaskEntityTypeEnum.Job);
|
||||
_logger.LogInformation("Синхронизация шаблонов завершена для Job '{JobName}' ({JobId})", context.JobName, jobId);
|
||||
}
|
||||
else
|
||||
{
|
||||
_logger.LogInformation("[DryRun] Write-этапы пропущены. Изменения в БД и MQ не выполнены.");
|
||||
await UpdateMatchingStatusAsync(jobId, "DryRun: Анализ завершён без изменений");
|
||||
await _matchingStatusService.DeleteMatchingStatusAsync(jobId, SyncTaskEntityTypeEnum.Job);
|
||||
}
|
||||
|
||||
totalSw.Stop();
|
||||
_logger.LogInformation("[Perf] Job '{JobName}' ({JobId}) | ИТОГО: {TotalMs} мс",
|
||||
context.JobName, jobId, totalSw.ElapsedMilliseconds);
|
||||
|
||||
await UpdateMatchingStatusAsync(jobId, "Синхронизация завершена успешно");
|
||||
await _matchingStatusService.DeleteMatchingStatusAsync(jobId, SyncTaskEntityTypeEnum.Job);
|
||||
_logger.LogInformation("Синхронизация шаблонов завершена для Job '{JobName}' ({JobId})",
|
||||
context.JobName, jobId);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
totalSw.Stop();
|
||||
_logger.LogError(ex, "Ошибка при синхронизации Job '{JobName}' ({JobId}) через {ElapsedMs} мс",
|
||||
string.Empty, jobId, totalSw.ElapsedMilliseconds);
|
||||
context.JobName ?? string.Empty, jobId, totalSw.ElapsedMilliseconds);
|
||||
await UpdateMatchingStatusAsync(jobId, $"Ошибка: {ex.Message}");
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public async Task SyncTemplatesForJobGroupAsync(Guid jobGroupId, HistoryInitiator initiator)
|
||||
private void PrintDryRunReport(SimpleSyncContext context)
|
||||
{
|
||||
_logger.LogWarning("SimpleTemplateSynchronizer: SyncTemplatesForJobGroup вызван для JobGroup {JobGroupId}. Это не поддерживаемая операция.", jobGroupId);
|
||||
_logger.LogInformation("========== [DryRun] ОТЧЁТ по Job '{JobName}' ({JobId}) ==========",
|
||||
context.JobName, context.JobId);
|
||||
|
||||
_logger.LogInformation("[DryRun] Отфильтровано юнитов: {Count}", context.FilteredUnitIds.Count);
|
||||
_logger.LogInformation("[DryRun] Существующих активных шаблонов: {Count}", context.ExistingUsedTemplates.Count);
|
||||
_logger.LogInformation("[DryRun] Новых юнитов (требуют аллокации): {Count}", context.NewUnitIds.Count);
|
||||
_logger.LogInformation("[DryRun] Шаблонов для деактивации (Unused): {Count}", context.UnusedTemplates.Count);
|
||||
_logger.LogInformation("[DryRun] Шаблонов для переименования: {Count}", context.TemplatesToRename.Count);
|
||||
|
||||
if (context.NewUnitIds.Any())
|
||||
{
|
||||
_logger.LogInformation("[DryRun] --- Новые юниты (будут созданы шаблоны) ---");
|
||||
foreach (var unitId in context.NewUnitIds)
|
||||
{
|
||||
_logger.LogInformation("[DryRun] + {Unit}", context.FormatUnit(unitId));
|
||||
}
|
||||
}
|
||||
|
||||
if (context.UnusedTemplates.Any())
|
||||
{
|
||||
_logger.LogInformation("[DryRun] --- Шаблоны для деактивации ---");
|
||||
foreach (var template in context.UnusedTemplates)
|
||||
{
|
||||
_logger.LogInformation("[DryRun] - {TemplateId} (Unit: {Unit}, Name: '{Name}')",
|
||||
template.Id, context.FormatUnit(template.UnitId), template.Name);
|
||||
}
|
||||
}
|
||||
|
||||
if (context.TemplatesToRename.Any())
|
||||
{
|
||||
_logger.LogInformation("[DryRun] --- Шаблоны для переименования ---");
|
||||
foreach (var (template, expectedName) in context.TemplatesToRename)
|
||||
{
|
||||
_logger.LogInformation("[DryRun] ~ {TemplateId} (Unit: {Unit}): '{OldName}' -> '{NewName}'",
|
||||
template.Id, context.FormatUnit(template.UnitId), template.Name, expectedName);
|
||||
}
|
||||
}
|
||||
|
||||
_logger.LogInformation("========== [DryRun] КОНЕЦ ОТЧЁТА ==========");
|
||||
}
|
||||
|
||||
public Task SyncTemplatesForJobGroupAsync(Guid jobGroupId, HistoryInitiator initiator, bool dryRun = false)
|
||||
{
|
||||
_logger.LogWarning(
|
||||
"SimpleTemplateSynchronizer: SyncTemplatesForJobGroup вызван для JobGroup {JobGroupId} (DryRun={DryRun}). Это не поддерживаемая операция.",
|
||||
jobGroupId, dryRun);
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
|
||||
@@ -278,7 +335,7 @@ internal class SimpleTemplateSynchronizer : ITemplateSynchronizer
|
||||
}
|
||||
|
||||
|
||||
private async Task SyncUnusedTemplatesAsync(Guid unusedJobId, HistoryInitiator initiator, CancellationToken ct = default)
|
||||
private async Task SyncUnusedTemplatesAsync(Guid unusedJobId, HistoryInitiator initiator, bool dryRun = false, CancellationToken ct = default)
|
||||
{
|
||||
// Проверка отмены в самом начале
|
||||
ct.ThrowIfCancellationRequested();
|
||||
@@ -467,9 +524,18 @@ internal class SimpleTemplateSynchronizer : ITemplateSynchronizer
|
||||
continue;
|
||||
}
|
||||
|
||||
await SendUpdateRequest(template, unusedJobId, expectedName, initiator, finalUnitId);
|
||||
_logger.LogDebug("Отправлен запрос на обновление шаблона {TemplateId}. Изменения: Unit={U}, Job={J}, Name={N}",
|
||||
template.Id, unitChanged, jobChanged, nameChanged);
|
||||
// Условие DryRun для отправки в MQ
|
||||
if (!dryRun)
|
||||
{
|
||||
await SendUpdateRequest(template, unusedJobId, expectedName, initiator, finalUnitId);
|
||||
_logger.LogDebug("Отправлен запрос на обновление шаблона {TemplateId}. Изменения: Unit={U}, Job={J}, Name={N}",
|
||||
template.Id, unitChanged, jobChanged, nameChanged);
|
||||
}
|
||||
else
|
||||
{
|
||||
_logger.LogInformation("[DryRun] Пропущена отправка запроса на обновление шаблона {TemplateId}. Изменения: Unit={U}, Job={J}, Name={N}, ExpectedName='{Name}'",
|
||||
template.Id, unitChanged, jobChanged, nameChanged, expectedName);
|
||||
}
|
||||
|
||||
processed++;
|
||||
}
|
||||
@@ -482,13 +548,20 @@ internal class SimpleTemplateSynchronizer : ITemplateSynchronizer
|
||||
|
||||
totalSw.Stop();
|
||||
|
||||
totalSw.Stop();
|
||||
_logger.LogInformation("[Perf] Job '{JobName}' ({JobId}) | ИТОГО: {TotalMs} мс",
|
||||
unusedJob.Name, unusedJob.Id, totalSw.ElapsedMilliseconds);
|
||||
|
||||
await UpdateMatchingStatusAsync(unusedJobId, "Синхронизация неиспользуемых шаблонов завершена");
|
||||
if (dryRun)
|
||||
{
|
||||
await UpdateMatchingStatusAsync(unusedJobId, "DryRun: Анализ неиспользуемых шаблонов завершён без изменений");
|
||||
}
|
||||
else
|
||||
{
|
||||
await UpdateMatchingStatusAsync(unusedJobId, "Синхронизация неиспользуемых шаблонов завершена");
|
||||
}
|
||||
|
||||
await _matchingStatusService.DeleteMatchingStatusAsync(unusedJobId, SyncTaskEntityTypeEnum.Job);
|
||||
totalSw.Stop();
|
||||
|
||||
_logger.LogInformation(
|
||||
"Синхронизация неиспользуемых шаблонов завершена. Обработано {Count} шаблонов",
|
||||
unusedTemplates.Count);
|
||||
|
||||
Reference in New Issue
Block a user