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