using EgwCoreLib.Utils; using GPW.CORE.Data; using GPW.CORE.Data.DbModels; using GPW.CORE.Data.DTO; using Microsoft.AspNetCore.Identity.UI.Services; using Newtonsoft.Json; using NLog; using StackExchange.Redis; using System.Diagnostics; using System.Text; namespace GPW.CORE.WRKLOG.old.Data { public class GpwDataService : IDisposable { #region Public Fields public static CORE.Data.Controllers.GPWController dbController = null!; public bool VetoInsert = false; #endregion Public Fields #region Public Constructors public GpwDataService(IConfiguration configuration, ILogger logger, IConnectionMultiplexer redisConnMult, IEmailSender emailSender) { _logger = logger; _configuration = configuration; _emailSender = emailSender; // Conf cache redisConn = redisConnMult;// ConnectionMultiplexer.Connect(_configuration.GetConnectionString("Redis")); //redisConn = ConnectionMultiplexer.Connect(_configuration.GetConnectionString("Redis")); redisDb = this.redisConn.GetDatabase(); // json serializer... FIX errore loop circolare https://www.ryadel.com/en/jsonserializationexception-self-referencing-loop-detected-error-fix-entity-framework-asp-net-core/ JSSettings = new JsonSerializerSettings() { ReferenceLoopHandling = ReferenceLoopHandling.Ignore }; // cod app CodApp = _configuration["CodApp"]; var strVeto = _configuration["VetoIns"]; _ = bool.TryParse(strVeto, out VetoInsert); // Conf DB string connStr = _configuration.GetConnectionString("GPW.DB"); if (string.IsNullOrEmpty(connStr)) { _logger.LogError("ConnString empty!"); } else { dbController = new CORE.Data.Controllers.GPWController(configuration); } // init datapipe... mPipeTimb = new MessagePipe(redisConn, Const.rPipeChTimb); mPipeRich = new MessagePipe(redisConn, Const.rPipeChRich); _logger.LogInformation("Avviata classe GpwDataService"); } #endregion Public Constructors #region Public Properties public string CodApp { get; set; } = ""; /// /// Pipe messaggi richieste /// public MessagePipe mPipeRich { get; set; } = null!; /// /// Pipe messaggi timbrature /// public MessagePipe mPipeTimb { get; set; } = null!; #endregion Public Properties #region Public Methods /// /// Elenco AKV /// public async Task?> AKVList() { string source = "DB"; List? dbResult = new List(); // cerco da cache string currKey = rKeyAKV; Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); string? rawData = await redisDb.StringGetAsync(currKey); if (!string.IsNullOrEmpty(rawData)) { source = "REDIS"; var tempResult = JsonConvert.DeserializeObject>(rawData); if (tempResult == null) { dbResult = new List(); } else { dbResult = tempResult; } } else { dbResult = dbController.AnagKeyValGetAll(); rawData = JsonConvert.SerializeObject(dbResult, JSSettings); await redisDb.StringSetAsync(currKey, rawData, UltraLongCache); } if (dbResult == null) { dbResult = new List(); } stopWatch.Stop(); TimeSpan ts = stopWatch.Elapsed; Log.Debug($"AKVList | {source} in: {ts.TotalMilliseconds} ms"); return dbResult; } /// /// Recupera l'elenco fasi (tutte) /// /// public async Task> AnagClientiAll() { string source = "DB"; List? dbResult = new List(); string currKey = $"{rKeyCliAll}"; Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); string? rawData = await redisDb.StringGetAsync(currKey); if (!string.IsNullOrEmpty(rawData)) { source = "REDIS"; var tempResult = JsonConvert.DeserializeObject>(rawData); if (tempResult == null) { dbResult = new List(); } else { dbResult = tempResult; } } else { dbResult = dbController.AnagClientiAll(); rawData = JsonConvert.SerializeObject(dbResult, JSSettings); await redisDb.StringSetAsync(currKey, rawData, LongCache); } if (dbResult == null) { dbResult = new List(); } stopWatch.Stop(); TimeSpan ts = stopWatch.Elapsed; Log.Debug($"AnagClientiAll | {source} in: {ts.TotalMilliseconds} ms"); return dbResult; } /// /// Recupera l'elenco fasi (tutte) /// /// public async Task> AnagFasiAll() { string source = "DB"; List? dbResult = new List(); string currKey = $"{rKeyFasiAll}"; Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); string? rawData = await redisDb.StringGetAsync(currKey); if (!string.IsNullOrEmpty(rawData)) { source = "REDIS"; var tempResult = JsonConvert.DeserializeObject>(rawData); if (tempResult == null) { dbResult = new List(); } else { dbResult = tempResult; } } else { dbResult = dbController.AnagFasiAll(false); rawData = JsonConvert.SerializeObject(dbResult, JSSettings); await redisDb.StringSetAsync(currKey, rawData, LongCache); } if (dbResult == null) { dbResult = new List(); } stopWatch.Stop(); TimeSpan ts = stopWatch.Elapsed; Log.Debug($"AnagFasiAll | {source} in: {ts.TotalMilliseconds} ms"); return dbResult; } /// /// Recupera info x una specifica FASE /// /// public async Task AnagFasiByKey(int idxFase) { string source = "DB"; AnagFasiModel? dbResult = new AnagFasiModel(); // cerco "secca "in redis... string currKey = $"{rKeyFasiSearch}:{idxFase}"; Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); string? rawData = await redisDb.StringGetAsync(currKey); if (!string.IsNullOrEmpty(rawData)) { source = "REDIS"; var tempResult = JsonConvert.DeserializeObject(rawData); if (tempResult == null) { dbResult = new AnagFasiModel(); } else { dbResult = tempResult; } } else { dbResult = dbController.AnagFasiByKey(idxFase); rawData = JsonConvert.SerializeObject(dbResult, JSSettings); await redisDb.StringSetAsync(currKey, rawData, UltraLongCache); } stopWatch.Stop(); TimeSpan ts = stopWatch.Elapsed; Log.Debug($"AnagFasiSearch | {source} in: {ts.TotalMilliseconds} ms"); return dbResult; } /// /// Elenco fasi dato progetto /// /// /// public async Task?> AnagFasiByProj(int idxProj) { string source = "DB"; List? dbResult = new List(); // cerco "secca "in redis... string currKey = $"{rKeyFasiByProj}:{idxProj}"; Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); string? rawData = await redisDb.StringGetAsync(currKey); if (!string.IsNullOrEmpty(rawData)) { source = "REDIS"; var tempResult = JsonConvert.DeserializeObject>(rawData); if (tempResult == null) { dbResult = new List(); } else { dbResult = tempResult; } } else { dbResult = dbController.AnagFasiByProj(idxProj); rawData = JsonConvert.SerializeObject(dbResult, JSSettings); await redisDb.StringSetAsync(currKey, rawData, LongCache); } if (dbResult == null) { dbResult = new List(); } stopWatch.Stop(); TimeSpan ts = stopWatch.Elapsed; Log.Debug($"AnagFasiByProj | {source} in: {ts.TotalMilliseconds} ms"); return dbResult; } /// /// Elenco Giustificativi /// /// public async Task?> AnagGiust() { string source = "DB"; List? dbResult = new List(); // cerco "secca "in redis... string currKey = $"{rKeyGiust}"; Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); string? rawData = await redisDb.StringGetAsync(currKey); if (!string.IsNullOrEmpty(rawData)) { source = "REDIS"; var tempResult = JsonConvert.DeserializeObject>(rawData); if (tempResult == null) { dbResult = new List(); } else { dbResult = tempResult; } } else { dbResult = dbController.AnagGiust(); rawData = JsonConvert.SerializeObject(dbResult, JSSettings); await redisDb.StringSetAsync(currKey, rawData, LongCache); } if (dbResult == null) { dbResult = new List(); } stopWatch.Stop(); TimeSpan ts = stopWatch.Elapsed; Log.Debug($"AnagGiust | {source} in: {ts.TotalMilliseconds} ms"); return dbResult; } /// /// Recupera l'elenco gruppi abilitati x il dipendente /// /// /// public async Task> AnagGruppiUser(int idxDipendente) { string source = "DB"; List? dbResult = new List(); string currKey = $"{rKeyGrpUser}:{idxDipendente}"; Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); string? rawData = await redisDb.StringGetAsync(currKey); if (!string.IsNullOrEmpty(rawData)) { source = "REDIS"; var tempResult = JsonConvert.DeserializeObject>(rawData); if (tempResult == null) { dbResult = new List(); } else { dbResult = tempResult; } } else { dbResult = dbController.AnagGruppiUser(idxDipendente); rawData = JsonConvert.SerializeObject(dbResult, JSSettings); await redisDb.StringSetAsync(currKey, rawData, LongCache); } if (dbResult == null) { dbResult = new List(); } stopWatch.Stop(); TimeSpan ts = stopWatch.Elapsed; Log.Debug($"AnagGruppiUser | {source} in: {ts.TotalMilliseconds} ms"); return dbResult; } /// /// Dati orario del dipendente indicato /// /// /// public async Task AnagOrarioByDip(int idxDip) { string source = "DB"; AnagOrariModel? dbResult = new AnagOrariModel(); string currKey = $"{rKeyAnOrDip}:{idxDip}"; Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); string? rawData = await redisDb.StringGetAsync(currKey); if (!string.IsNullOrEmpty(rawData)) { source = "REDIS"; var tempResult = JsonConvert.DeserializeObject(rawData); if (tempResult == null) { dbResult = new AnagOrariModel(); } else { dbResult = tempResult; } } else { dbResult = dbController.AnagOrarioByDip(idxDip); rawData = JsonConvert.SerializeObject(dbResult, JSSettings); await redisDb.StringSetAsync(currKey, rawData, LongCache); } if (dbResult == null) { dbResult = new AnagOrariModel(); } stopWatch.Stop(); TimeSpan ts = stopWatch.Elapsed; Log.Debug($"AnagOrarioByDip | {source} in: {ts.TotalMilliseconds} ms"); return dbResult; } /// /// Recupera l'elenco progetti (tutti) /// /// public async Task> AnagProjAll() { string source = "DB"; List? dbResult = new List(); string currKey = $"{rKeyProjAll}"; Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); string? rawData = await redisDb.StringGetAsync(currKey); if (!string.IsNullOrEmpty(rawData)) { source = "REDIS"; var tempResult = JsonConvert.DeserializeObject>(rawData); if (tempResult == null) { dbResult = new List(); } else { dbResult = tempResult; } } else { dbResult = dbController.AnagProjAll(false); rawData = JsonConvert.SerializeObject(dbResult, JSSettings); await redisDb.StringSetAsync(currKey, rawData, UltraLongCache); } if (dbResult == null) { dbResult = new List(); } stopWatch.Stop(); TimeSpan ts = stopWatch.Elapsed; Log.Debug($"AnagProjAll | {source} in: {ts.TotalMilliseconds} ms"); return dbResult; } /// /// Recupera info x uno specifico PROJ /// /// public async Task AnagProjSearch(int idxProj) { AnagProgettiModel dbResult = new AnagProgettiModel(); var rawData = await AnagProjAll(); if (rawData != null) { var foundData = rawData.Where(x => x.IdxProgetto == idxProj).FirstOrDefault(); if (foundData != null) { dbResult = foundData; } } return dbResult; } /// /// Vista dati per FASE (tipicamente master...) con totalizzaizone ore budget/real e stato fase /// /// /// public async Task CalcOreFase(int idxFase) { string source = "DB"; CalcOreFasiModel? dbResult = new CalcOreFasiModel(); string currKey = $"{rKeyCalcOreFase}:{idxFase}"; Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); string? rawData = await redisDb.StringGetAsync(currKey); if (!string.IsNullOrEmpty(rawData)) { source = "REDIS"; var tempResult = JsonConvert.DeserializeObject(rawData); if (tempResult == null) { dbResult = new CalcOreFasiModel(); } else { dbResult = tempResult; } } else { dbResult = dbController.CalcOreFase(idxFase); rawData = JsonConvert.SerializeObject(dbResult, JSSettings); await redisDb.StringSetAsync(currKey, rawData, LongCache); } if (dbResult == null) { dbResult = new CalcOreFasiModel(); } stopWatch.Stop(); TimeSpan ts = stopWatch.Elapsed; Log.Debug($"CalcOreFase | {source} in: {ts.TotalMilliseconds} ms"); return dbResult; } /// /// Vista dati per progetto con totalizzaizone ore budget/real /// /// /// public async Task CalcOreProj(int idxProj) { string source = "DB"; CalcOreProgettiModel? dbResult = new CalcOreProgettiModel(); string currKey = $"{rKeyCalcOreProj}:{idxProj}"; Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); string? rawData = await redisDb.StringGetAsync(currKey); if (!string.IsNullOrEmpty(rawData)) { source = "REDIS"; var tempResult = JsonConvert.DeserializeObject(rawData); if (tempResult == null) { dbResult = new CalcOreProgettiModel(); } else { dbResult = tempResult; } } else { dbResult = dbController.CalcOreProj(idxProj); rawData = JsonConvert.SerializeObject(dbResult, JSSettings); await redisDb.StringSetAsync(currKey, rawData, LongCache); } if (dbResult == null) { dbResult = new CalcOreProgettiModel(); } stopWatch.Stop(); TimeSpan ts = stopWatch.Elapsed; Log.Debug($"CalcOreProj | {source} in: {ts.TotalMilliseconds} ms"); return dbResult; } /// /// Lista chiusure aziendali dato periodo /// /// /// /// public async Task> CalFestFeriePeriodo(DateTime dtStart, DateTime dtEnd) { string source = "DB"; List? dbResult = new List(); string currKey = $"{rKeyCalendari}:ClaFestFer:{dtStart:yyyyMMdd}:{dtEnd:yyyyMMdd}"; Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); string? rawData = await redisDb.StringGetAsync(currKey); if (!string.IsNullOrEmpty(rawData)) { source = "REDIS"; var tempResult = JsonConvert.DeserializeObject>(rawData); if (tempResult == null) { dbResult = new List(); } else { dbResult = tempResult; } } else { dbResult = dbController.CalFestFeriePeriodo(dtStart, dtEnd); rawData = JsonConvert.SerializeObject(dbResult, JSSettings); await redisDb.StringSetAsync(currKey, rawData, LongCache); } if (dbResult == null) { dbResult = new List(); } stopWatch.Stop(); TimeSpan ts = stopWatch.Elapsed; Log.Debug($"CalFestFeriePeriodo | {source} in: {ts.TotalMilliseconds} ms"); return dbResult; } /// /// Recupera l'elenco dei controlli VC19 nel periodo indicato x dipendente /// /// Dipendente interessato /// Data di riferimento (ultima/corrente) /// NUm settimane precedenti da recuperare /// public async Task> CheckVC19List(int idxDipendente, DateTime dtInizio, DateTime dtFine) { string source = "DB"; List? dbResult = new List(); string currKey = $"{rKeyVC19}:{dtInizio:yyyyMMdd}:{dtFine:yyyMMdd}"; Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); string? rawData = await redisDb.StringGetAsync(currKey); if (!string.IsNullOrEmpty(rawData)) { source = "REDIS"; var tempResult = JsonConvert.DeserializeObject>(rawData); if (tempResult == null) { dbResult = new List(); } else { dbResult = tempResult; } } else { dbResult = dbController.CheckVC19List(idxDipendente, dtInizio, dtFine); rawData = JsonConvert.SerializeObject(dbResult, JSSettings); await redisDb.StringSetAsync(currKey, rawData, LongCache); } if (dbResult == null) { dbResult = new List(); } stopWatch.Stop(); TimeSpan ts = stopWatch.Elapsed; Log.Debug($"CheckVC19List | {source} in: {ts.TotalMilliseconds} ms"); return dbResult; } /// /// Lista configurazione /// /// /// /// public async Task> ConfigGetAll() { string source = "DB"; List? dbResult = new List(); string currKey = $"{rKeyConfig}:Table"; Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); string? rawData = await redisDb.StringGetAsync(currKey); if (!string.IsNullOrEmpty(rawData)) { source = "REDIS"; var tempResult = JsonConvert.DeserializeObject>(rawData); if (tempResult == null) { dbResult = new List(); } else { dbResult = tempResult; } } else { dbResult = dbController.ConfigGetAll(); rawData = JsonConvert.SerializeObject(dbResult, JSSettings); await redisDb.StringSetAsync(currKey, rawData, UltraLongCache); } if (dbResult == null) { dbResult = new List(); } stopWatch.Stop(); TimeSpan ts = stopWatch.Elapsed; Log.Debug($"ConfigGetAll | {source} in: {ts.TotalMilliseconds} ms"); return dbResult; } /// /// Recupera una singola chaive di config da cache/DB /// /// /// public async Task ConfigGetKey(string chiave) { string source = "DB"; // cerco in cache direttamente la chiave... altrimenti da redis/db ConfigModel? keyResult = null; string currKey = $"{rKeyConfig}:Dict:{chiave}"; Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); string? rawData = await redisDb.StringGetAsync(currKey); if (!string.IsNullOrEmpty(rawData)) { source = "REDIS"; var tempResult = JsonConvert.DeserializeObject(rawData); if (tempResult == null) { keyResult = new ConfigModel(); } else { keyResult = tempResult; } keyResult = JsonConvert.DeserializeObject(rawData); } else { var listConfig = await ConfigGetAll(); keyResult = listConfig.FirstOrDefault(x => x.chiave == chiave); rawData = JsonConvert.SerializeObject(keyResult, JSSettings); await redisDb.StringSetAsync(currKey, rawData, UltraLongCache); } stopWatch.Stop(); TimeSpan ts = stopWatch.Elapsed; Log.Debug($"ConfigGetKey | {chiave} | {source} in: {ts.TotalMilliseconds} ms"); return await Task.FromResult(keyResult); } /// /// Recupera l'elenco dei dettaglio giornaliero attività di tutti i dipendenti, dato giorno riferimento /// /// Data di riferimento /// public async Task> DailyDetailAllDip(DateTime dtRif) { string source = "DB"; List? dbResult = new List(); string currKey = $"{rKeyDailyData}:ALL:{dtRif.ToString("yyyy-MM-dd")}"; Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); string? rawData = await redisDb.StringGetAsync(currKey); if (!string.IsNullOrEmpty(rawData)) { source = "REDIS"; var tempResult = JsonConvert.DeserializeObject>(rawData); if (tempResult == null) { dbResult = new List(); } else { dbResult = tempResult; } } else { dbResult = dbController.DailyDetailAllDip(dtRif); rawData = JsonConvert.SerializeObject(dbResult, JSSettings); await redisDb.StringSetAsync(currKey, rawData, FastCache); } if (dbResult == null) { dbResult = new List(); } stopWatch.Stop(); TimeSpan ts = stopWatch.Elapsed; Log.Debug($"DailyDetailAllDip | {source} in: {ts.TotalMilliseconds} ms"); return dbResult; } /// /// Recupera l'elenco delle ultime attività inserite da un dipendente /// /// Dipendente interessato /// Num record da recuperare /// public async Task> UserLastRec(int idxDipendente, int numRec) { string source = "DB"; DateTime oggi = DateTime.Today; List? dbResult = new List(); string currKey = $"{rKeyLastRegAtt}:{idxDipendente}:{oggi.ToString("yyyy-MM-dd")}:{numRec}"; Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); string? rawData = await redisDb.StringGetAsync(currKey); if (!string.IsNullOrEmpty(rawData)) { source = "REDIS"; var tempResult = JsonConvert.DeserializeObject>(rawData); if (tempResult == null) { dbResult = new List(); } else { dbResult = tempResult; } } else { dbResult = dbController.UserLastRec(idxDipendente, numRec); rawData = JsonConvert.SerializeObject(dbResult, JSSettings); await redisDb.StringSetAsync(currKey, rawData, FastCache); } if (dbResult == null) { dbResult = new List(); } stopWatch.Stop(); TimeSpan ts = stopWatch.Elapsed; Log.Debug($"UserLastRec | {source} in: {ts.TotalMilliseconds} ms"); return dbResult; } /// /// Recupera l'elenco dei dettagli giornalieri attività di un dipendente, dato periodo riferimento /// /// Dipendente interessato /// Data inizio periodo /// Data fine periodo /// public async Task> DailyDetails(int idxDipendente, DateTime dtInizio, DateTime dtFine) { string source = "DB"; List? dbResult = new List(); string currKey = $"{rKeyDailyData}:{idxDipendente}:{dtInizio.ToString("yyyy-MM-dd")}:{dtFine.ToString("yyyy-MM-dd")}"; Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); string? rawData = await redisDb.StringGetAsync(currKey); if (!string.IsNullOrEmpty(rawData)) { source = "REDIS"; var tempResult = JsonConvert.DeserializeObject>(rawData); if (tempResult == null) { dbResult = new List(); } else { dbResult = tempResult; } } else { dbResult = dbController.DailyDetails(idxDipendente, dtInizio, dtFine); rawData = JsonConvert.SerializeObject(dbResult, JSSettings); await redisDb.StringSetAsync(currKey, rawData, FastCache); } if (dbResult == null) { dbResult = new List(); } stopWatch.Stop(); TimeSpan ts = stopWatch.Elapsed; Log.Debug($"DailyDetails | {source} in: {ts.TotalMilliseconds} ms"); return dbResult; } public string DeriptData(string encData) { return EgwCoreLib.Utils.SteamCrypto.DecryptString(encData, passPhrase); } public async Task> DipendentiGetAll() { string source = "DB"; List? dbResult = new List(); string currKey = rKeyDipendenti; Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); string? rawData = await redisDb.StringGetAsync(currKey); if (!string.IsNullOrEmpty(rawData)) { source = "REDIS"; var tempResult = JsonConvert.DeserializeObject>(rawData); if (tempResult == null) { dbResult = new List(); } else { dbResult = tempResult; } } else { dbResult = dbController.DipendentiGetAll(); rawData = JsonConvert.SerializeObject(dbResult, JSSettings); await redisDb.StringSetAsync(currKey, rawData, UltraLongCache); } if (dbResult == null) { dbResult = new List(); } stopWatch.Stop(); TimeSpan ts = stopWatch.Elapsed; Log.Debug($"DipendentiGetAll | {source} in: {ts.TotalMilliseconds} ms"); return dbResult; } public void Dispose() { // Clear database controller dbController.Dispose(); GC.Collect(); } public string EncriptData(string rawData) { return EgwCoreLib.Utils.SteamCrypto.EncryptString(rawData, passPhrase); } public async Task FlushRedisCache() { await Task.Delay(1); RedisValue pattern = new RedisValue($"{redisBaseAddr}:*"); bool answ = await ExecFlushRedisPattern(pattern); return answ; } /// /// Statistiche ultime settimane /// /// /// /// /// public async Task> LastWeeks(int idxDipendente, DateTime dtRif, int numWeek) { string source = "DB"; List? dbResult = new List(); string currKey = $"{rKeyWeekStats}:{idxDipendente}:{dtRif.ToString("yyyy-MM-dd")}:{numWeek}"; Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); string? rawData = await redisDb.StringGetAsync(currKey); if (!string.IsNullOrEmpty(rawData)) { source = "REDIS"; var tempResult = JsonConvert.DeserializeObject>(rawData); if (tempResult == null) { dbResult = new List(); } else { dbResult = tempResult; } } else { dbResult = dbController.WeekOverview(idxDipendente, dtRif, numWeek); rawData = JsonConvert.SerializeObject(dbResult, JSSettings); await redisDb.StringSetAsync(currKey, rawData, LongCache); } if (dbResult == null) { dbResult = new List(); } stopWatch.Stop(); TimeSpan ts = stopWatch.Elapsed; Log.Debug($"LastWeeks | {source} in: {ts.TotalMilliseconds} ms"); return dbResult; } /// /// Elenco pareto progetti ordinati da filtro /// /// /// /// /// public async Task> ParetoRegAtt(int idxDip, int numDayPrev, int maxResult) { string source = "DB"; DateTime dataFine = DateTime.Today.AddDays(1); DateTime dataInizio = dataFine.AddDays(-numDayPrev); List? dbResult = new List(); string currKey = $"{rKeyParetoRegAtt}:{idxDip}:{numDayPrev}:{maxResult}"; Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); string? rawData = await redisDb.StringGetAsync(currKey); if (!string.IsNullOrEmpty(rawData)) { source = "REDIS"; var tempResult = JsonConvert.DeserializeObject>(rawData); if (tempResult == null) { dbResult = new List(); } else { dbResult = tempResult; } } else { dbResult = dbController.ParetoRegAtt(idxDip, dataInizio, dataFine, maxResult); rawData = JsonConvert.SerializeObject(dbResult, JSSettings); await redisDb.StringSetAsync(currKey, rawData, LongCache); } if (dbResult == null) { dbResult = new List(); } stopWatch.Stop(); TimeSpan ts = stopWatch.Elapsed; Log.Debug($"ParetoRegAtt | {source} in: {ts.TotalMilliseconds} ms"); return dbResult; } /// /// Righe presenze giornaliere /// /// DataOra riferimento per richiesta presenze /// public async Task> PresenzeDay(DateTime dtRif) { string source = "DB"; List dbResult = new List(); string currKey = $"{rKeyStatPresDay}:{dtRif:yyyy-MM-dd}"; Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); string? rawData = await redisDb.StringGetAsync(currKey); if (!string.IsNullOrEmpty(rawData)) { source = "REDIS"; var tempResult = JsonConvert.DeserializeObject>(rawData); if (tempResult == null) { dbResult = new List(); } else { dbResult = tempResult; } } else { dbResult = dbController.PresenzeDay(dtRif); rawData = JsonConvert.SerializeObject(dbResult, JSSettings); await redisDb.StringSetAsync(currKey, rawData, FastCache); } if (dbResult == null) { dbResult = new List(); } stopWatch.Stop(); TimeSpan ts = stopWatch.Elapsed; Log.Debug($"PresenzeDay | {source} in: {ts.TotalMilliseconds} ms"); return dbResult; } public async Task RegAttDelete(RegAttivitaModel currItem) { bool answ = false; try { dbController.RegAttDelete(currItem); // invalido la cache... await ExecFlushRedisPattern($"{rKeyDailyData}:*"); await ExecFlushRedisPattern($"{rKeyLastRegAtt}:*"); await ExecFlushRedisPattern($"{rKeyParetoRegAtt}:*"); await ExecFlushRedisPattern($"{rKeyWeekStats}:*"); answ = true; } catch { } return answ; } /// /// Recupera ultima attività dipendente /// /// /// cerca ultima solo tra attive (=true) o tutte (=false) /// public async Task RegAttLastByDip(int IdxDipendente, bool onlyActive) { await Task.Delay(1); RegAttivitaModel dbResult = dbController.RegAttLastByDip(IdxDipendente, onlyActive); return dbResult; } public async Task RegAttUpdate(RegAttivitaModel currItem) { bool answ = false; try { dbController.RegAttUpdate(currItem); // invalido la cache... await ExecFlushRedisPattern($"{rKeyDailyData}:*"); await ExecFlushRedisPattern($"{rKeyLastRegAtt}:*"); await ExecFlushRedisPattern($"{rKeyParetoRegAtt}:*"); await ExecFlushRedisPattern($"{rKeyWeekStats}:*"); answ = true; } catch { } return answ; } /// /// Effettua eliminazione record registro malattie (SE non confermato) /// /// /// public async Task RegMalattieDelete(RegMalattieModel currItem) { bool answ = false; try { answ = dbController.RegMalattieDelete(currItem); if (answ) { // recupero info dipendente var listDip = await DipendentiGetAll(); var currDip = listDip.FirstOrDefault(x => x.IdxDipendente == currItem.IdxDipendente); // gestisco email notifica... string emailDest = _configuration["MailDest:InfoMal"]; if (currDip.idxResp > 0) { string mailResp = await emailResp(currDip.idxResp); if (!string.IsNullOrEmpty(mailResp) && !emailDest.Contains(mailResp)) { emailDest += $",{mailResp}"; } } string urlRedir = _configuration["AdmApp:LinkMal"]; StringBuilder sbMain = new StringBuilder(); DateTime adesso = DateTime.Now; sbMain.AppendLine($"Il giorno {adesso:yyyy.MM.dd} alle ore {adesso:HH:mm:ss} è stato rimosso un record di registrazione malattia"); sbMain.AppendLine(""); sbMain.Append("
"); sbMain.Append($"{currItem.DipNav.Cognome} {currItem.DipNav.Nome} ({currItem.DipNav.Matricola})"); //sbMain.Append($"{currDip.Cognome} {currDip.Nome} ({currDip.Matricola})"); sbMain.Append("
"); sbMain.AppendLine("
"); sbMain.AppendLine($"Data Inizio: {currItem.DtInizio}"); sbMain.AppendLine($"Numero Giorni: {currItem.NumGG}"); sbMain.AppendLine($"Certificato: {currItem.CodCert}"); sbMain.AppendLine("
"); sbMain.AppendLine($"Cliccare sul seguente link per accedere alla pagina di gestione"); string msgBody = sbMain.ToString(); await sendEmail(emailDest, "Eliminazione record Malattia Dipendente", msgBody.Replace($"{Environment.NewLine}", "
")); } // invalido la cache... await ExecFlushRedisPattern($"{rKeyDipendenti}:*"); } catch { } return answ; } /// /// Restituisce elenco malattie globali /// /// max record da recuperare /// public async Task> RegMalattieGetAll(int maxRecord) { string source = "DB"; List? dbResult = new List(); string currKey = $"{rKeyDipendenti}:ALL:RegMal:{maxRecord}"; Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); string? rawData = await redisDb.StringGetAsync(currKey); if (!string.IsNullOrEmpty(rawData)) { source = "REDIS"; var tempResult = JsonConvert.DeserializeObject>(rawData); if (tempResult == null) { dbResult = new List(); } else { dbResult = tempResult; } } else { dbResult = dbController.RegMalattieGetAll(maxRecord); rawData = JsonConvert.SerializeObject(dbResult, JSSettings); await redisDb.StringSetAsync(currKey, rawData, FastCache); } if (dbResult == null) { dbResult = new List(); } stopWatch.Stop(); TimeSpan ts = stopWatch.Elapsed; Log.Debug($"RegMalattieGetAll | {source} in: {ts.TotalMilliseconds} ms"); return dbResult; } /// /// Restituisce elenco malattie dipendente /// /// Dipendente interessato /// max record da recuperare /// public async Task> RegMalattieGetByDip(int idxDipendente, int maxRecord) { string source = "DB"; List? dbResult = new List(); string currKey = $"{rKeyDipendenti}:{idxDipendente}:RegMal:{maxRecord}"; Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); string? rawData = await redisDb.StringGetAsync(currKey); if (!string.IsNullOrEmpty(rawData)) { source = "REDIS"; var tempResult = JsonConvert.DeserializeObject>(rawData); if (tempResult == null) { dbResult = new List(); } else { dbResult = tempResult; } } else { dbResult = dbController.RegMalattieGetByDip(idxDipendente, maxRecord); rawData = JsonConvert.SerializeObject(dbResult, JSSettings); await redisDb.StringSetAsync(currKey, rawData, FastCache); } if (dbResult == null) { dbResult = new List(); } stopWatch.Stop(); TimeSpan ts = stopWatch.Elapsed; Log.Debug($"RegMalattieGetByDip | {source} in: {ts.TotalMilliseconds} ms"); return dbResult; } /// /// Registra o aggiorna record registro malattie /// /// /// public async Task RegMalattieUpsert(RegMalattieModel currItem) { bool answ = false; try { // scrivo su DB answ = dbController.RegMalattieUpsert(currItem); if (answ) { // recupero info dipendente var listDip = await DipendentiGetAll(); var currDip = listDip.FirstOrDefault(x => x.IdxDipendente == currItem.IdxDipendente); // gestisco email notifica... string emailDest = _configuration["MailDest:InfoMal"]; if (currDip.idxResp > 0) { string mailResp = await emailResp(currDip.idxResp); if (!string.IsNullOrEmpty(mailResp) && !emailDest.Contains(mailResp)) { emailDest += $",{mailResp}"; } } string urlRedir = _configuration["AdmApp:LinkMal"]; StringBuilder sbMain = new StringBuilder(); DateTime adesso = DateTime.Now; sbMain.AppendLine($"Il giorno {adesso:yyyy.MM.dd} alle ore {adesso:HH:mm:ss} è stato inserito un nuovo record di registrazione malattia"); sbMain.AppendLine(""); sbMain.Append("
"); sbMain.Append($"{currDip.Cognome} {currDip.Nome} ({currDip.Matricola})"); sbMain.Append("
"); sbMain.AppendLine("
"); sbMain.AppendLine($"Data Inizio: {currItem.DtInizio}"); sbMain.AppendLine($"Numero Giorni: {currItem.NumGG}"); sbMain.AppendLine($"Certificato: {currItem.CodCert}"); sbMain.AppendLine("
"); sbMain.AppendLine($"Cliccare sul seguente link per accedere alla pagina di gestione"); string msgBody = sbMain.ToString(); await sendEmail(emailDest, "Nuovo record Malattia Dipendente", msgBody.Replace($"{Environment.NewLine}", "
")); } // invalido la cache... await ExecFlushRedisPattern($"{rKeyDipendenti}:*"); } catch { } return answ; } /// /// Effettua eliminazione record registro richieste dipendente (SE non confermato) /// /// /// public async Task RegRichiesteDelete(RegRichiesteModel currItem) { bool answ = false; try { answ = dbController.RegRichiesteDelete(currItem); if (answ) { // recupero info dipendente var listDip = await DipendentiGetAll(); var currDip = listDip.FirstOrDefault(x => x.IdxDipendente == currItem.IdxDipendente); // gestisco email notifica... string emailDest = _configuration["MailDest:InfoRich"]; if (currDip.idxResp > 0) { string mailResp = await emailResp(currDip.idxResp); if (!string.IsNullOrEmpty(mailResp) && !emailDest.Contains(mailResp)) { emailDest += $",{mailResp}"; } } string urlRedir = _configuration["AdmApp:LinkRich"]; StringBuilder sbMain = new StringBuilder(); DateTime adesso = DateTime.Now; sbMain.AppendLine($"Il giorno {adesso:yyyy.MM.dd} alle ore {adesso:HH:mm:ss} è stato rimosso un record di registrazione richiesta utente"); sbMain.AppendLine(""); sbMain.Append("
"); sbMain.Append($"{currItem.DipNav.Cognome} {currItem.DipNav.Nome} ({currItem.DipNav.Matricola})"); //sbMain.Append($"{currDip.Cognome} {currDip.Nome} ({currDip.Matricola})"); sbMain.Append("
"); sbMain.AppendLine("
"); sbMain.AppendLine($"Richiesta: {currItem.CodGiust}"); sbMain.AppendLine($"Periodo: {currItem.DtStart} --> {currItem.DtEnd}"); sbMain.AppendLine($"Note: {currItem.Note}"); sbMain.AppendLine("
"); sbMain.AppendLine($"Cliccare sul seguente link per accedere alla pagina di gestione"); string msgBody = sbMain.ToString(); await sendEmail(emailDest, $"Eliminazione Richiesta Dipendente | {currItem.CodGiust}", msgBody.Replace($"{Environment.NewLine}", "
")); } // invalido la cache... await ExecFlushRedisPattern($"{rKeyDipendenti}:*"); await ExecFlushRedisPattern($"{rKeyDailyData}:*"); await ExecFlushRedisPattern($"{rKeyLastRegAtt}:*"); await ExecFlushRedisPattern($"{rKeyParetoRegAtt}:*"); await ExecFlushRedisPattern($"{rKeyWeekStats}:*"); } catch { } return answ; } /// /// Restituisce elenco richieste dipendente /// /// Dipendente interessato /// Inizio periodo richiesto /// Fine periodo richiesto /// public async Task> RegRichiesteGetByDip(int idxDipendente, DateTime dtFrom, DateTime dtTo) { string source = "DB"; List? dbResult = new List(); string currKey = $"{rKeyDipendenti}:{idxDipendente}:RegRichieste:{dtFrom:yyyyMMdd}:{dtTo:yyyyMMdd}"; Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); string? rawData = await redisDb.StringGetAsync(currKey); if (!string.IsNullOrEmpty(rawData)) { source = "REDIS"; var tempResult = JsonConvert.DeserializeObject>(rawData); if (tempResult == null) { dbResult = new List(); } else { dbResult = tempResult; } } else { dbResult = dbController.RegRichiesteGetByDip(idxDipendente, dtFrom, dtTo); rawData = JsonConvert.SerializeObject(dbResult, JSSettings); await redisDb.StringSetAsync(currKey, rawData, FastCache); } if (dbResult == null) { dbResult = new List(); } stopWatch.Stop(); TimeSpan ts = stopWatch.Elapsed; Log.Debug($"RegRichiesteGetByDip | {source} in: {ts.TotalMilliseconds} ms"); return dbResult; } /// /// Registra o aggiorna record registro richieste /// /// /// public async Task RegRichiesteUpsert(RegRichiesteModel currItem) { bool answ = false; try { // scrivo su DB answ = dbController.RegRichiesteUpsert(currItem); if (answ) { // recupero info dipendente var listDip = await DipendentiGetAll(); var currDip = listDip.FirstOrDefault(x => x.IdxDipendente == currItem.IdxDipendente); // gestisco email notifica... string emailDest = _configuration["MailDest:InfoRich"]; if (currDip.idxResp > 0) { string mailResp = await emailResp(currDip.idxResp); if (!string.IsNullOrEmpty(mailResp) && !emailDest.Contains(mailResp)) { emailDest += $",{mailResp}"; } } string urlRedir = _configuration["AdmApp:LinkRich"]; StringBuilder sbMain = new StringBuilder(); DateTime adesso = DateTime.Now; sbMain.AppendLine($"Il giorno {adesso:yyyy.MM.dd} alle ore {adesso:HH:mm:ss} è stato inserito una nuova richiesta dipendente"); sbMain.AppendLine(""); sbMain.Append("
"); sbMain.Append($"{currDip.Cognome} {currDip.Nome} ({currDip.Matricola})"); sbMain.Append("
"); sbMain.AppendLine("
"); sbMain.AppendLine($"Richiesta: {currItem.CodGiust}"); sbMain.AppendLine($"Periodo: {currItem.DtStart} --> {currItem.DtEnd}"); sbMain.AppendLine($"Note: {currItem.Note}"); sbMain.AppendLine("
"); sbMain.AppendLine($"Cliccare sul seguente link per accedere alla pagina di gestione"); string msgBody = sbMain.ToString(); await sendEmail(emailDest, $"Nuovo record Richiesta {currItem.CodGiust} Dipendente", msgBody.Replace($"{Environment.NewLine}", "
")); } // invalido la cache... await ExecFlushRedisPattern($"{rKeyDipendenti}:*"); await ExecFlushRedisPattern($"{rKeyDailyData}:*"); await ExecFlushRedisPattern($"{rKeyLastRegAtt}:*"); await ExecFlushRedisPattern($"{rKeyParetoRegAtt}:*"); await ExecFlushRedisPattern($"{rKeyWeekStats}:*"); } catch { } return answ; } /// /// Recupera l'elenco dei dettagli attività e timbrature di un dipendente, dato periodo riferimento /// /// Dipendente interessato /// Periodo di riferimento /// public async Task ReportDetails(int idxDipendente, DtUtils.Periodo periodo) { string source = "DB"; ReportDataDTO? dbResult = new ReportDataDTO(); string currKey = $"{rKeyReportData}:{idxDipendente}:{periodo.Inizio.ToString("yyyy-MM-dd")}:{periodo.Fine.ToString("yyyy-MM-dd")}"; Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); string? rawData = await redisDb.StringGetAsync(currKey); if (!string.IsNullOrEmpty(rawData)) { source = "REDIS"; var tempResult = JsonConvert.DeserializeObject(rawData); if (tempResult == null) { dbResult = new ReportDataDTO(); } else { dbResult = tempResult; } } else { dbResult = dbController.ReportDetails(idxDipendente, periodo); rawData = JsonConvert.SerializeObject(dbResult, JSSettings); await redisDb.StringSetAsync(currKey, rawData, LongCache); } if (dbResult == null) { dbResult = new ReportDataDTO(); } stopWatch.Stop(); TimeSpan ts = stopWatch.Elapsed; Log.Debug($"ReportDetails | {source} in: {ts.TotalMilliseconds} ms"); return dbResult; } /// /// Reset dati report x dipendente, se 0 = tutti /// /// /// public async Task ReportResetCacheDip(int idxDipendente) { if (idxDipendente == 0) { await ExecFlushRedisPattern($"{rKeyReportData}:*"); } else { await ExecFlushRedisPattern($"{rKeyReportData}:{idxDipendente}:*"); } } /// /// Recupera l'elenco dei Rilievi temperatura nel periodo indicato x dipendente /// /// Dipendente interessato /// Data di riferimento (ultima/corrente) /// NUm settimane precedenti da recuperare /// public async Task> RilTempList(int idxDipendente, DateTime dtInizio, DateTime dtFine) { string source = "DB"; List? dbResult = new List(); string currKey = $"{rKeyRilTemp}:{dtInizio:yyyyMMdd}:{dtFine:yyyMMdd}"; Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); string? rawData = await redisDb.StringGetAsync(currKey); if (!string.IsNullOrEmpty(rawData)) { source = "REDIS"; var tempResult = JsonConvert.DeserializeObject>(rawData); if (tempResult == null) { dbResult = new List(); } else { dbResult = tempResult; } } else { dbResult = dbController.RilTempList(idxDipendente, dtInizio, dtFine); rawData = JsonConvert.SerializeObject(dbResult, JSSettings); await redisDb.StringSetAsync(currKey, rawData, FastCache); } if (dbResult == null) { dbResult = new List(); } stopWatch.Stop(); TimeSpan ts = stopWatch.Elapsed; Log.Debug($"RilTempList | {source} in: {ts.TotalMilliseconds} ms"); return dbResult; } public async Task RilTempUpdate(RilievoTempModel currItem) { bool answ = false; try { dbController.RilTempUpdate(currItem); // invalido la cache... await ExecFlushRedisPattern($"{rKeyRilTemp}:*"); await ExecFlushRedisPattern($"{rKeyDailyData}:*"); await ExecFlushRedisPattern($"{rKeyLastRegAtt}:*"); await ExecFlushRedisPattern($"{rKeyParetoRegAtt}:*"); await ExecFlushRedisPattern($"{rKeyWeekStats}:*"); answ = true; } catch { } return answ; } public void rollBackEdit(object item) { dbController.rollBackEntity(item); } /// /// Elenco timbrature di un giorno /// /// /// /// public async Task> TimbratureDay(DateTime dateRif, int IdxDip) { await Task.Delay(1); List? dbResult = new List(); Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); dbResult = dbController.TimbratureDay(dateRif, IdxDip); stopWatch.Stop(); TimeSpan ts = stopWatch.Elapsed; Log.Trace($"Effettuata lettura da DB + caching per TimbratureDay: {ts.TotalMilliseconds} ms"); return dbResult; } public async Task TimbratureDelete(TimbratureModel currItem) { bool answ = false; try { dbController.TimbratureDelete(currItem); // invalido la cache... await FlushRedisCache(); answ = true; } catch { } return answ; } public async Task TimbratureUpdate(TimbratureModel currItem) { bool answ = false; try { dbController.TimbratureUpdate(currItem); // invalido la cache... await FlushRedisCache(); answ = true; } catch { } return answ; } #endregion Public Methods #region Protected Fields protected const string passPhrase = "6E1DA6B4-4647-4578-AB4F-01360E2B7E68"; protected const string redisBaseAddr = "WrkLog"; protected const string rKeyAKV = $"{redisBaseAddr}:Cache:AKV"; protected const string rKeyAnOrDip = $"{redisBaseAddr}:Cache:AnOrariDip"; protected const string rKeyCalcOreFase = $"{redisBaseAddr}:Cache:CalcOreFase"; protected const string rKeyCalcOreProj = $"{redisBaseAddr}:Cache:CalcOreProj"; protected const string rKeyCalendari = $"{redisBaseAddr}:Cache:Calendari"; protected const string rKeyCliAll = $"{redisBaseAddr}:Cache:CliAll"; protected const string rKeyConfig = $"{redisBaseAddr}:Cache:Config"; protected const string rKeyDailyData = $"{redisBaseAddr}:Cache:DailyData"; protected const string rKeyLastRegAtt = $"{redisBaseAddr}:Cache:LastRegAtt"; protected const string rKeyDipendenti = $"{redisBaseAddr}:Cache:Dipendenti"; protected const string rKeyFasiAll = $"{redisBaseAddr}:Cache:FasiAll"; protected const string rKeyFasiByProj = $"{redisBaseAddr}:Cache:FasiByProj"; protected const string rKeyFasiSearch = $"{redisBaseAddr}:Cache:FasiSearch"; protected const string rKeyGiust = $"{redisBaseAddr}:Cache:Giustif"; protected const string rKeyGrpAll = $"{redisBaseAddr}:Cache:GrpAll"; protected const string rKeyGrpUser = $"{redisBaseAddr}:Cache:GrpUser"; protected const string rKeyParetoRegAtt = $"{redisBaseAddr}:Cache:ParetoRegAtt"; protected const string rKeyProjAll = $"{redisBaseAddr}:Cache:ProjAll"; protected const string rKeyReportData = $"{redisBaseAddr}:Cache:ReportData"; protected const string rKeyRilTemp = $"{redisBaseAddr}:Cache:RilTemp"; protected const string rKeyStatPresDay = $"{redisBaseAddr}:Cache:StatPresDay"; protected const string rKeyVC19 = $"{redisBaseAddr}:Cache:VC19"; protected const string rKeyVetoIns = $"{redisBaseAddr}:Cache:VetoInsert"; protected const string rKeyWeekStats = $"{redisBaseAddr}:Cache:WeekStats"; protected static string connStringBBM = ""; protected Random rnd = new Random(); #endregion Protected Fields #region Protected Methods /// /// Calcola email del responsabile dato idx /// /// /// protected async Task emailResp(int idxResp) { string answ = ""; var listDip = await DipendentiGetAll(); // recupero email resp... if (idxResp > 0) { var recResp = listDip.FirstOrDefault(x => x.IdxDipendente == idxResp); if (recResp != null) { answ = $"{recResp.Email}"; } } return answ; } /// /// Invio email tramite libreria /// /// /// /// /// protected async Task sendEmail(string destList, string subject, string message) { List emailDestList = destList.Split(",").ToList(); foreach (var dest in emailDestList) { try { await _emailSender.SendEmailAsync(dest, subject, message); } catch (Exception exc) { Log.Error($"Eccezione durante invio email:{Environment.NewLine}dest: {dest} | subject {subject}{Environment.NewLine}{exc}"); } } } #endregion Protected Methods #region Private Fields private static IConfiguration _configuration = null!; private static ILogger _logger = null!; private static JsonSerializerSettings? JSSettings; private static NLog.Logger Log = LogManager.GetCurrentClassLogger(); private readonly IEmailSender _emailSender; /// /// Durata cache lunga IN SECONDI /// private int cacheTtlLong = 60 * 5; /// /// Durata cache breve IN SECONDI /// private int cacheTtlShort = 60 * 1; /// /// Oggetto per connessione a REDIS /// private IConnectionMultiplexer redisConn; //ISubscriber sub = redis.GetSubscriber(); /// /// Oggetto DB redis da impiegare x chiamate R/W /// private IDatabase redisDb = null!; #endregion Private Fields #region Private Properties /// /// Durata cache veloce (+ perturbazione percentuale +/-10%) /// private TimeSpan FastCache { get => TimeSpan.FromSeconds(cacheTtlShort * rnd.Next(900, 1100) / 1000); } /// /// Durata cache lunga (+ perturbazione percentuale +/-10%) /// private TimeSpan LongCache { get => TimeSpan.FromSeconds(cacheTtlLong * rnd.Next(900, 1100) / 1000); } /// /// Durata cache ultra-lunga (+ perturbazione percentuale +/-10%) /// private TimeSpan UltraLongCache { get => TimeSpan.FromSeconds(cacheTtlLong * 10 * rnd.Next(900, 1100) / 1000); } #endregion Private Properties #region Private Methods /// /// Esegue flush memoria redis dato pattern /// /// /// private async Task ExecFlushRedisPattern(RedisValue pattern) { bool answ = false; var listEndpoints = redisConn.GetEndPoints(); foreach (var endPoint in listEndpoints) { //var server = redisConnAdmin.GetServer(listEndpoints[0]); var server = redisConn.GetServer(endPoint); if (server != null) { var keyList = server.Keys(redisDb.Database, pattern); foreach (var item in keyList) { await redisDb.KeyDeleteAsync(item); } answ = true; } } return answ; } #endregion Private Methods } }