feat(core, infrastructure): RedisCacheService - изменение/добавление полей в кэше списокм. UnitCacheService - оптимизация при получении данных.

This commit is contained in:
Mikhail Trubnikov
2026-06-03 12:09:47 +10:00
parent d1de63e939
commit 66d1fe7b0d
4 changed files with 87 additions and 9 deletions

View File

@@ -86,6 +86,16 @@
/// <returns></returns>
Task SetHashFieldAsync<T>(string hashKey, string field, T value, TimeSpan? ttl = null, bool useCompression = false);
/// <summary>
/// Изменить несколько полей в Hash
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="items"></param>
/// <param name="ttl">Если указано, обновится у всего Hash. Если не указано и hash не существовал, создастся Hash с бесокнечным ttl</param>
/// <param name="useCompression">Сжимать данные</param>
/// <returns></returns>
Task SetHashFieldsAsync<T>(List<(string HashKey, string FieldKey, T Value)> items, TimeSpan? ttl = null, bool useCompression = false);
/// <summary>
/// Получить значение поля из Hash
/// </summary>

View File

@@ -1,5 +1,6 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json.Linq;
using PARR.Core.Common.Interfaces;
using PARR.Core.Repositories.Interfaces.Unit;
using PARR.Domain.Cache;
@@ -17,6 +18,11 @@ namespace PARR.Core.Services.UnitService.Implementations
/// </summary>
private readonly TimeSpan CacheTtl = TimeSpan.FromHours(24);
/// <summary>
/// Размер порции данных, для запроса в БД
/// </summary>
private readonly int DatabaseBatchSize = 500;
private readonly ILogger<UnitCacheService> logger;
private readonly IUnitRepository unitRepository;
private readonly IRedisCacheService redisCacheService;
@@ -102,6 +108,9 @@ namespace PARR.Core.Services.UnitService.Implementations
var dbData = await GetUnitsAsync(missingIds);
// список объектов для сохранения в кэш
var dataToCache = new List<(string HashKey, string FieldKey, UnitInfo Value)>();
foreach (var unit in dbData)
{
resultDictionary[unit.Id] = unit;
@@ -110,11 +119,13 @@ namespace PARR.Core.Services.UnitService.Implementations
var hashKey = redisCacheService.GetKey(CacheKeys.Unit.UnitHashWithBucket(unit.Id));
var unitKey = redisCacheService.GetKey(CacheKeys.Unit.UnitItem(unit.Id));
await redisCacheService.SetHashFieldAsync(hashKey, unitKey, unit, CacheTtl, true);
//await redisCacheService.SetHashFieldAsync(hashKey, unitKey, unit, CacheTtl, true);
dataToCache.Add((hashKey, unitKey, unit));
}
}
// сохранить докаченные в кэш + ттл + не забыть указать сжатие (может вообще этот метод вынести отдельно, так как пересекается когда по одному)
if (dataToCache.Count > 0)
await redisCacheService.SetHashFieldsAsync<UnitInfo>(dataToCache, CacheTtl, true);
}
return resultDictionary;
}
@@ -225,7 +236,7 @@ namespace PARR.Core.Services.UnitService.Implementations
var dbUnits = new List<dynamic>();
// Выполняем порционно
foreach (var chank in ids.Chunk(500))
foreach (var chank in ids.Chunk(DatabaseBatchSize))
{
var chunkUnits = await unitRepository.Get()
.AsNoTracking()
@@ -260,7 +271,7 @@ namespace PARR.Core.Services.UnitService.Implementations
// Пакетно загружаем базовую информацию обо всех родственниках за один раз
var relativesDictionary = new Dictionary<Guid, UnitInfoBase>();
foreach (var chunk in allRelativeIds.Chunk(500))
foreach (var chunk in allRelativeIds.Chunk(DatabaseBatchSize))
{
var chunkRelatives = await unitRepository.Get()
.AsNoTracking()