feat(core, dal): WorkloadCacheService - методы для работы с кэшем отчетности workload
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
using Microsoft.Extensions.Caching.Distributed;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using PARR.Core.Common.Interfaces;
|
||||
using StackExchange.Redis;
|
||||
using System.Text.Json;
|
||||
@@ -8,14 +9,19 @@ namespace PARR.Infrastructure.Redis
|
||||
internal class RedisCacheService : IRedisCacheService
|
||||
{
|
||||
private readonly IDistributedCache cache;
|
||||
private readonly IConnectionMultiplexer connectionMultiplexer;
|
||||
private readonly ILogger<RedisCacheService> logger;
|
||||
private readonly IDatabase redis;
|
||||
|
||||
public RedisCacheService(
|
||||
IDistributedCache cache,
|
||||
IConnectionMultiplexer connectionMultiplexer
|
||||
IConnectionMultiplexer connectionMultiplexer,
|
||||
ILogger<RedisCacheService> logger
|
||||
)
|
||||
{
|
||||
this.cache = cache;
|
||||
this.connectionMultiplexer = connectionMultiplexer;
|
||||
this.logger = logger;
|
||||
this.redis = connectionMultiplexer.GetDatabase();
|
||||
}
|
||||
|
||||
@@ -80,6 +86,61 @@ namespace PARR.Infrastructure.Redis
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
public async Task<int> DeleteKeysByPatternAsync(string pattern, int batchSize = 100)
|
||||
{
|
||||
if (string.IsNullOrEmpty(pattern))
|
||||
return 0;
|
||||
|
||||
logger.LogDebug("Начало удаление ключей по маске '{Pattern}' из кэш", pattern);
|
||||
|
||||
var deletedCount = 0;
|
||||
var keysToDelete = new List<RedisKey>();
|
||||
|
||||
// Получаем сервер для выполнения SCAN
|
||||
//todo: Для кластера нужно обрабатывать каждый узел отдельно
|
||||
|
||||
var server = connectionMultiplexer.GetEndPoints()
|
||||
.Select(t => connectionMultiplexer.GetServer(t))
|
||||
.FirstOrDefault();
|
||||
|
||||
if (server == null)
|
||||
{
|
||||
logger.LogError("Не удалось получить сервер Redis для операции SCAN");
|
||||
return 0;
|
||||
}
|
||||
|
||||
// server.Keys() лениво сканирует ключи через SCAN (не блокирует!)
|
||||
// Важно: не вызывай .ToList() — это загрузит всё в память!
|
||||
foreach (var key in server.Keys(pattern: pattern, pageSize: batchSize))
|
||||
{
|
||||
keysToDelete.Add(key);
|
||||
|
||||
// Удаляем пакетом, чтобы не делать лишний сетевой запрос на каждый ключ
|
||||
if (keysToDelete.Count >= batchSize)
|
||||
{
|
||||
await redis.KeyDeleteAsync(keysToDelete.ToArray());
|
||||
deletedCount += keysToDelete.Count;
|
||||
|
||||
logger.LogDebug("Удалено {Count} ключей по масске '{Pattern}'", keysToDelete.Count, pattern);
|
||||
|
||||
keysToDelete.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
// Удаляем остаток, если остался
|
||||
if (keysToDelete.Count > 0)
|
||||
{
|
||||
await redis.KeyDeleteAsync(keysToDelete.ToArray());
|
||||
deletedCount += keysToDelete.Count;
|
||||
}
|
||||
|
||||
logger.LogInformation("Завершено удаление ключей по маске '{Pattern}'. Удалено: {DeletedCount}", pattern, deletedCount);
|
||||
|
||||
return deletedCount;
|
||||
}
|
||||
|
||||
|
||||
#region Нативные операции Redis, Redis Hash
|
||||
|
||||
public async Task SetHashFieldAsync<T>(string hashKey, string field, T value, TimeSpan? ttl = null)
|
||||
|
||||
Reference in New Issue
Block a user