using Microsoft.Extensions.Caching.Distributed; using Microsoft.Extensions.Caching.Memory; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Logging; using Newtonsoft.Json; using NLog; using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Text; using System.Threading.Tasks; namespace LiMan.UI.Data { public class LiManDataService : IDisposable { #region Private Fields private static IConfiguration _configuration; private static ILogger _logger; private static NLog.Logger Log = LogManager.GetCurrentClassLogger(); private readonly IDistributedCache distributedCache; private readonly IMemoryCache memoryCache; /// /// Durata assoluta massima della cache IN SECONDI /// private int chAbsExp = 60 * 5; /// /// Durata della cache IN SECONDI in modalità inattiva (non acceduta) prima di venire rimossa /// NON estende oltre il tempo massimo di validità della cache (chAbsExp) /// private int chSliExp = 60 * 1; #endregion Private Fields #region Protected Fields protected static string connStringBBM = ""; #endregion Protected Fields #region Public Fields public static LiMan.DL.Controllers.LicManController dbController; #endregion Public Fields #region Public Constructors public LiManDataService(IConfiguration configuration, ILogger logger, IMemoryCache memoryCache, IDistributedCache distributedCache) { _logger = logger; _configuration = configuration; // conf cache this.memoryCache = memoryCache; this.distributedCache = distributedCache; // conf DB string connStr = _configuration.GetConnectionString("LiMan.DB"); if (string.IsNullOrEmpty(connStr)) { _logger.LogError("ConnString empty!"); } else { dbController = new LiMan.DL.Controllers.LicManController(configuration); _logger.LogInformation("DbController OK"); } } #endregion Public Constructors #region Private Methods private DistributedCacheEntryOptions cacheOpt(bool fastCache) { var numSecAbsExp = fastCache ? chAbsExp : chAbsExp * 10; var numSecSliExp = fastCache ? chSliExp : chSliExp * 10; return new DistributedCacheEntryOptions().SetAbsoluteExpiration(DateTime.Now.AddSeconds(numSecAbsExp)).SetSlidingExpiration(TimeSpan.FromSeconds(numSecSliExp)); } #endregion Private Methods #region Protected Methods protected string getCacheKey(string TableName, SelectData CurrFilter) { string answ = $"{TableName}:D_{CurrFilter.DateStart:yyyyMMddHHmm}_{CurrFilter.DateEnd:yyyyMMddHHmm}"; return answ; } #endregion Protected Methods #region Public Methods /// /// Hash Redis contenente i dati MP di una specifico TYPE (es StatusMacchina, StateMachineIngressi, ...) /// /// /// public static string mHash(string dataType) { return $"DATA:{dataType}"; } public async Task> ApplicazioniGetAll() { List dbResult = new List(); string cacheKey = mHash("Applicazioni"); string rawData; var redisDataList = await distributedCache.GetAsync(cacheKey); if (redisDataList != null) { rawData = Encoding.UTF8.GetString(redisDataList); dbResult = JsonConvert.DeserializeObject>(rawData); } else { Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); dbResult = dbController.GetApplicazioni(); rawData = JsonConvert.SerializeObject(dbResult); redisDataList = Encoding.UTF8.GetBytes(rawData); await distributedCache.SetAsync(cacheKey, redisDataList, cacheOpt(false)); stopWatch.Stop(); TimeSpan ts = stopWatch.Elapsed; Log.Trace($"Effettuata lettura da DB + caching per ApplicazioniGetAll: {ts.TotalMilliseconds} ms"); } return await Task.FromResult(dbResult); } public async Task DbForceMigrate() { return await Task.FromResult(dbController.DbForceMigrate()); } public void Dispose() { // Clear database controller dbController.Dispose(); } public async Task> InstallazioniGetAll() { List dbResult = new List(); string cacheKey = mHash("Installazioni"); string rawData; var redisDataList = await distributedCache.GetAsync(cacheKey); if (redisDataList != null) { rawData = Encoding.UTF8.GetString(redisDataList); dbResult = JsonConvert.DeserializeObject>(rawData); } else { Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); dbResult = dbController.GetInstallazioni(); rawData = JsonConvert.SerializeObject(dbResult); redisDataList = Encoding.UTF8.GetBytes(rawData); await distributedCache.SetAsync(cacheKey, redisDataList, cacheOpt(false)); stopWatch.Stop(); TimeSpan ts = stopWatch.Elapsed; Log.Trace($"Effettuata lettura da DB + caching per InstallazioniGetAll: {ts.TotalMilliseconds} ms"); } return await Task.FromResult(dbResult); } /// /// invalida tutta la cache in caso di update /// /// public async Task InvalidateAllCache() { await distributedCache.RemoveAsync(mHash("Applicazioni")); await distributedCache.RemoveAsync(mHash("Installazioni")); await distributedCache.RemoveAsync(mHash("Licenze")); //await distributedCache.RemoveAsync(mHash("SUPPL:List")); //await distributedCache.RemoveAsync(mHash("TRANSP:List")); //await distributedCache.RemoveAsync(mHash("WEEKPLAN:List")); } public async Task> LicenzeGetAll() { List dbResult = new List(); string cacheKey = mHash("Licenze"); string rawData; var redisDataList = await distributedCache.GetAsync(cacheKey); if (redisDataList != null) { rawData = Encoding.UTF8.GetString(redisDataList); dbResult = JsonConvert.DeserializeObject>(rawData); } else { Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); dbResult = dbController.GetLicenze(); rawData = JsonConvert.SerializeObject(dbResult); redisDataList = Encoding.UTF8.GetBytes(rawData); await distributedCache.SetAsync(cacheKey, redisDataList, cacheOpt(false)); stopWatch.Stop(); TimeSpan ts = stopWatch.Elapsed; Log.Trace($"Effettuata lettura da DB + caching per LicenzeGetAll: {ts.TotalMilliseconds} ms"); } return await Task.FromResult(dbResult); } #endregion Public Methods } }