80 lines
2.9 KiB
C#
80 lines
2.9 KiB
C#
using Kit.Helpers.Postgres;
|
|
|
|
namespace Kit.Helpers;
|
|
|
|
/// <summary>
|
|
/// Провайдер кэша через самописную схему (и её элементы) distributed. <br />
|
|
/// </summary>
|
|
public class PgTableDistributedCacheService : IDistributedCacheService
|
|
{
|
|
private readonly IDistributedLockService _distributedLockService;
|
|
private readonly string _connectionString;
|
|
|
|
private const string _lockType = "PgTableDistributedCacheService";
|
|
|
|
public PgTableDistributedCacheService(
|
|
IConfigurationDistributedPg configuration,
|
|
IDistributedLockService distributedLockService)
|
|
{
|
|
_distributedLockService = distributedLockService;
|
|
_connectionString = configuration.DistributedConnectionString;
|
|
}
|
|
|
|
public void ExecuteOnLock(string key, Action action)
|
|
{
|
|
_distributedLockService.ExecuteOnLock(_lockType, key, action);
|
|
}
|
|
|
|
public TResult ExecuteOnLock<TResult>(string key, Func<TResult> action)
|
|
{
|
|
return _distributedLockService.ExecuteOnLock(_lockType, key, action);
|
|
}
|
|
|
|
public void SetCacheData<TObject>(string cacheName, TObject data, DistributedCacheOptions setProperties)
|
|
{
|
|
this.ExecuteOnLock(cacheName, () =>
|
|
{
|
|
var parameters = new List<KeyValuePair<string, object>>
|
|
{
|
|
new KeyValuePair<string, object>("_key", cacheName),
|
|
new KeyValuePair<string, object>("_value", data.JsonSerialize())
|
|
};
|
|
if (setProperties.AbsoluteExpirationRelativeToNow.HasValue)
|
|
{
|
|
parameters.Add(new KeyValuePair<string, object>("_absolute_expiration_seconds", (int)setProperties.AbsoluteExpirationRelativeToNow.Value.TotalSeconds));
|
|
}
|
|
if (setProperties.SlidingExpiration.HasValue)
|
|
{
|
|
parameters.Add(new KeyValuePair<string, object>("_sliding_expiration_seconds", (int)setProperties.SlidingExpiration.Value.TotalSeconds));
|
|
}
|
|
|
|
_connectionString.ExecuteNonQuery("distributed.cache_insert", isStoredProcedure: true, parameters);
|
|
});
|
|
}
|
|
|
|
public TResult? GetCacheData<TResult>(string cacheName)
|
|
{
|
|
return this.ExecuteOnLock(cacheName, () =>
|
|
{
|
|
var parameters = new List<KeyValuePair<string, object>>
|
|
{
|
|
new KeyValuePair<string, object>("_key", cacheName)
|
|
};
|
|
object? result = _connectionString.ExecuteScalar<object>("distributed.cache_select", isStoredProcedure: true, parameters:parameters);
|
|
|
|
if (result is not string jsonString)
|
|
{
|
|
return default;
|
|
}
|
|
|
|
try
|
|
{
|
|
return jsonString.JsonDeserialize<TResult>();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
throw new InvalidOperationException($"Error while deserializing json value of cache. cacheName: {cacheName}", ex);
|
|
}
|
|
});
|
|
}
|
|
} |