feat(core, infrastructure): IRedisCacheService - данные теперь можно архивировать
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
using Microsoft.Extensions.Caching.Distributed;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using PARR.Core.Common.Interfaces;
|
||||
using PARR.Infrastructure.Redis.Helpers;
|
||||
using StackExchange.Redis;
|
||||
using System.Text.Json;
|
||||
|
||||
@@ -8,6 +9,11 @@ namespace PARR.Infrastructure.Redis
|
||||
{
|
||||
internal class RedisCacheService : IRedisCacheService
|
||||
{
|
||||
/// <summary>
|
||||
/// Минимальный размер для сжатия
|
||||
/// </summary>
|
||||
private const int compressionTreshold = 10 * 1024; // 10Kb
|
||||
|
||||
private readonly IDistributedCache cache;
|
||||
private readonly IConnectionMultiplexer connectionMultiplexer;
|
||||
private readonly ILogger<RedisCacheService> logger;
|
||||
@@ -27,49 +33,87 @@ namespace PARR.Infrastructure.Redis
|
||||
|
||||
#region Распределенный кэш IDistributedCache
|
||||
|
||||
public async Task<T?> GetCachedDataAsync<T>(string key)
|
||||
public async Task<T?> GetCachedDataAsync<T>(string key, bool useCompression = false)
|
||||
{
|
||||
var jsonData = await cache.GetStringAsync(key);
|
||||
if (useCompression)
|
||||
{
|
||||
// хранили в байтах
|
||||
try
|
||||
{
|
||||
var data = await cache.GetAsync(key);
|
||||
if (data == null)
|
||||
return default(T);
|
||||
|
||||
if (jsonData == null)
|
||||
return default(T);
|
||||
return DeserializeWithCompression<T>(data);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new Exception("Формат данных не байты.", ex);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// хранили в строке
|
||||
try
|
||||
{
|
||||
var jsonData = await cache.GetStringAsync(key);
|
||||
|
||||
return JsonSerializer.Deserialize<T>(jsonData);
|
||||
if (jsonData == null)
|
||||
return default(T);
|
||||
|
||||
return JsonSerializer.Deserialize<T>(jsonData);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new Exception("Формат данных не строка.", ex);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public T? GetCachedData<T>(string key)
|
||||
{
|
||||
var jsonData = cache.GetString(key);
|
||||
//public T? GetCachedData<T>(string key)
|
||||
//{
|
||||
// var jsonData = cache.GetString(key);
|
||||
|
||||
if (jsonData == null)
|
||||
return default(T);
|
||||
// if (jsonData == null)
|
||||
// return default(T);
|
||||
|
||||
return JsonSerializer.Deserialize<T>(jsonData);
|
||||
}
|
||||
// return JsonSerializer.Deserialize<T>(jsonData);
|
||||
//}
|
||||
|
||||
|
||||
public void SetCachedData<T>(string key, T data, TimeSpan cacheDuration)
|
||||
//public void SetCachedData<T>(string key, T data, TimeSpan cacheDuration)
|
||||
//{
|
||||
// var options = new DistributedCacheEntryOptions
|
||||
// {
|
||||
// AbsoluteExpirationRelativeToNow = cacheDuration
|
||||
// };
|
||||
|
||||
// var jsonData = JsonSerializer.Serialize(data);
|
||||
// cache.SetString(key, jsonData, options);
|
||||
//}
|
||||
|
||||
|
||||
public async Task SetCachedDataAsync<T>(string key, T data, TimeSpan cacheDuration, bool useCompression = false)
|
||||
{
|
||||
var options = new DistributedCacheEntryOptions
|
||||
{
|
||||
AbsoluteExpirationRelativeToNow = cacheDuration
|
||||
};
|
||||
|
||||
var jsonData = JsonSerializer.Serialize(data);
|
||||
cache.SetString(key, jsonData, options);
|
||||
}
|
||||
|
||||
|
||||
public async Task SetCachedDataAsync<T>(string key, T data, TimeSpan cacheDuration)
|
||||
{
|
||||
var options = new DistributedCacheEntryOptions
|
||||
if (useCompression)
|
||||
{
|
||||
AbsoluteExpirationRelativeToNow = cacheDuration
|
||||
};
|
||||
|
||||
var jsonData = JsonSerializer.Serialize(data);
|
||||
await cache.SetStringAsync(key, jsonData, options);
|
||||
// храним в байтах, если надо то сжимаем
|
||||
var jsonData = SerializeWithCompression(data);
|
||||
await cache.SetAsync(key, jsonData, options);
|
||||
}
|
||||
else
|
||||
{
|
||||
// храним в строке
|
||||
var jsonData = JsonSerializer.Serialize(data);
|
||||
await cache.SetStringAsync(key, jsonData, options);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -250,5 +294,28 @@ namespace PARR.Infrastructure.Redis
|
||||
|
||||
#endregion
|
||||
|
||||
private byte[] SerializeWithCompression<T>(T data)
|
||||
{
|
||||
var json = JsonSerializer.SerializeToUtf8Bytes(data);
|
||||
|
||||
logger.LogDebug("Сериализовано: {Size} байт, тип: {Type}", json.Length, typeof(T).Name);
|
||||
|
||||
if (json.Length < compressionTreshold)
|
||||
return json;
|
||||
|
||||
var compressed = CompressionHelper.Compress(json);
|
||||
logger.LogDebug("После сжатия: {Size} байт (экономия: {Percent}%)", compressed.Length, Math.Round((1 - (double)compressed.Length / json.Length) * 100, 1));
|
||||
|
||||
return compressed;
|
||||
}
|
||||
|
||||
private T? DeserializeWithCompression<T>(byte[] data)
|
||||
{
|
||||
var json = CompressionHelper.Decompress(data);
|
||||
|
||||
return JsonSerializer.Deserialize<T>(json);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user