Files
parr_api/PARR.Core/Services/Snapshots/Implementations/RobotConfigurationSnapshotService.cs

95 lines
4.5 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using PARR.Core.Repositories.Interfaces;
using PARR.Core.Repositories.Interfaces.RobotRepositories;
using PARR.Core.Services.Snapshots.Interfaces;
using PARR.Domain.Entities.RobotEntities;
using PARR.Domain.Exceptions;
namespace PARR.Core.Services.Snapshots.Implementations
{
/// <summary>
/// Снапшоты для таблицы RobotConfiguration
/// </summary>
internal class RobotConfigurationSnapshotService : ISnapshotProvider
{
private readonly IRobotConfigurationRepository _robotConfigurationRepository;
private readonly IRobotConfigurationSnapshotRepository _robotConfigurationSnapshotRepository;
private readonly ILogger<RobotConfigurationSnapshotService> _logger;
private readonly ISnapshotSettings _snapshotSettings;
public TimeSpan Interval => _snapshotSettings.RobotConfigurationSnapshotInterval;// TimeSpan.FromMinutes(2);
public TimeSpan RetentionPeriod => _snapshotSettings.RobotConfigurationSnapshotRetentionPeriod;//TimeSpan.FromDays(60);
public RobotConfigurationSnapshotService(
IRobotConfigurationRepository robotConfigurationRepository,
IRobotConfigurationSnapshotRepository robotConfigurationSnapshotRepository,
ILogger<RobotConfigurationSnapshotService> logger,
ISnapshotSettings snapshotSettings
)
{
_robotConfigurationRepository = robotConfigurationRepository;
_robotConfigurationSnapshotRepository = robotConfigurationSnapshotRepository;
_logger = logger;
_snapshotSettings = snapshotSettings;
}
public async Task TakeSnapshotAsync(CancellationToken cancellationToken)
{
var now = DateTimeOffset.UtcNow;
_logger.LogDebug("Сбор метрик для снапшота RobotConfigurations...");
var stats = await _robotConfigurationRepository.Get()
.GroupBy(t => new { t.RobotCode, t.RobotStatusCode, t.TaskStatusCode })
.Select(g => new
{
g.Key.RobotCode,
g.Key.RobotStatusCode,
g.Key.TaskStatusCode,
Count = g.Count()
})
.ToListAsync(cancellationToken);
if (!stats.Any())
{
_logger.LogDebug("Нет активных заданий роботов для создания снапшота.");
return;
}
var snapshots = stats.Select(s => new RobotConfigurationSnapshot
{
Id = Guid.NewGuid(),
DateCreated = now,
RobotCode = s.RobotCode,
RobotStatusCode = s.RobotStatusCode,
TaskStatusCode = s.TaskStatusCode,
Count = s.Count
}).ToList();
if (!await _robotConfigurationSnapshotRepository.AddRangeAsync(snapshots) || !await _robotConfigurationSnapshotRepository.CommitAsync())
throw new DbErrorException("Ошибка при сохранении в БД");
_logger.LogInformation("Успешно сохранен снапшот RobotConfigurations. Записано строк: {Count}. Периодичность: {Interval}", snapshots.Count, Interval);
}
public async Task CleanUpOldSnapshotsAsync(CancellationToken cancellationToken)
{
// Вычисляем граничную дату (всё, что было ДО нее — удаляем)
var thresholdDate = DateTimeOffset.UtcNow.Subtract(RetentionPeriod);
_logger.LogInformation("[{ServiceName}] Запуск очистки старых снапшотов. Удаление данных старше {ThresholdDate}", GetType().Name, thresholdDate);
// Фильтруем старые записи и вызываем ExecuteDeleteAsync для удаления прямо в базе данных
var deletedCount = await _robotConfigurationSnapshotRepository.Get()
.Where(s => s.DateCreated < thresholdDate)
.ExecuteDeleteAsync(cancellationToken);
_logger.LogInformation("[{ServiceName}] Очистка завершена. Удалено устаревших строк снапшотов: {Count}", GetType().Name, deletedCount);
}
}
}