95 lines
4.5 KiB
C#
95 lines
4.5 KiB
C#
|
|
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);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|