diff --git a/MP.Data/Controllers/MpSpecController.cs b/MP.Data/Controllers/MpSpecController.cs index 4186b6d5..1b5bab5b 100644 --- a/MP.Data/Controllers/MpSpecController.cs +++ b/MP.Data/Controllers/MpSpecController.cs @@ -2198,25 +2198,14 @@ namespace MP.Data.Controllers /// /// /// - public PODLModel PODL_getByOdl(int idxODL) + public async Task PODL_getByOdlAsync(int idxODL) { - PODLModel dbResult = new PODLModel(); - using (var dbCtx = new MoonProContext(options)) - { - try - { - dbResult = dbCtx - .DbSetPODL - .AsNoTracking() - .Where(x => x.IdxOdl == idxODL) - .FirstOrDefault(); - } - catch (Exception exc) - { - Log.Error($"Eccezione durante PODL_getByOdl{Environment.NewLine}{exc}"); - } - } - return dbResult; + using var dbCtx = new MoonProContext(options); + return await dbCtx + .DbSetPODL + .AsNoTracking() + .Where(x => x.IdxOdl == idxODL) + .FirstOrDefaultAsync() ?? new(); } /// diff --git a/MP.SPEC/Components/ListODL.razor.cs b/MP.SPEC/Components/ListODL.razor.cs index 47129602..7347ec53 100644 --- a/MP.SPEC/Components/ListODL.razor.cs +++ b/MP.SPEC/Components/ListODL.razor.cs @@ -123,7 +123,7 @@ namespace MP.SPEC.Components // ricarica... await selRecord(null); } - await ReloadData(); + await ReloadDataAsync(); } /// @@ -151,18 +151,12 @@ namespace MP.SPEC.Components // ricarica... await selRecord(null); } - await ReloadData(); + await ReloadDataAsync(); } protected int getPodl(int idxOdl) { - int answ = 0; - var pOdlData = MDService.POdlGetByOdl(idxOdl); - if (pOdlData != null) - { - answ = pOdlData.IdxPromessa; - } - return answ; + return _podlLocalCache.TryGetValue(idxOdl, out var val) ? val : 0; } /// @@ -227,13 +221,13 @@ namespace MP.SPEC.Components protected override async Task OnParametersSetAsync() { - await ReloadData(); + await ReloadDataAsync(); } protected async Task resetSel() { await selRecord(null); - await ReloadData(); + await ReloadDataAsync(); } protected async Task selBrowseRecord(ODLExpModel? currRec) @@ -276,7 +270,7 @@ namespace MP.SPEC.Components protected async Task UpdateData() { await selRecord(null); - await ReloadData(); + await ReloadDataAsync(); } #endregion Protected Methods @@ -360,14 +354,39 @@ namespace MP.SPEC.Components #region Private Methods - private async Task ReloadData() + private async Task ReloadDataAsync() { isLoading = true; SearchRecords = await MDService.OdlListGetFilt(currFilter.IsActive, currFilter.SearchVal, currFilter.CodFase, currFilter.CodReparto, currFilter.IdxMacchina, currFilter.DtStart, currFilter.DtEnd); + await ReloadPOdlData(); totalCount = SearchRecords.Count; ListRecords = SearchRecords.Skip(numRecord * (currPage - 1)).Take(numRecord).ToList(); isLoading = false; } + private Dictionary _podlLocalCache = new(); + private async Task ReloadPOdlData() + { + _podlLocalCache.Clear(); + if (SearchRecords != null) + { + // 1. Popolo la cache locale in parallelo sfruttando la velocità di FusionCache + var tasks = SearchRecords.Select(async odl => + { + int podl = 0; + var pOdlData = await MDService.POdlGetByOdlAsync(odl.IdxOdl); // Tua nuova versione Async + if (pOdlData != null) + { + podl = pOdlData.IdxPromessa; + } + return (odl.IdxOdl, podl); + }); + + var infoSalvate = await Task.WhenAll(tasks); + + // 2. Trasformazione dei risultati in un dizionario per l'accesso immediato (O(1)) nell'HTML + _podlLocalCache = infoSalvate.ToDictionary(x => x.IdxOdl, x => x.podl); + } + } private async Task reloadStatsData(ODLExpModel? currRec) { diff --git a/MP.SPEC/Data/MpDataService.cs b/MP.SPEC/Data/MpDataService.cs index 4e2a0c2a..d12b3fed 100644 --- a/MP.SPEC/Data/MpDataService.cs +++ b/MP.SPEC/Data/MpDataService.cs @@ -213,7 +213,7 @@ namespace MP.SPEC.Data return await GetOrFetchAsync( operationName: "AnagStatiCommAsync", cacheKey: Utils.redisStatoCom, - expiration: TimeSpan.FromMinutes(redisLongTimeCache), + expiration: TimeSpan.FromSeconds(redisLongTimeCache), fetchFunc: async () => await dbController.AnagStatiCommAsync() ?? new List(), tagList: [Utils.redisStatoCom] @@ -229,7 +229,7 @@ namespace MP.SPEC.Data return await GetOrFetchAsync( operationName: "AnagTipoArtLvAsync", cacheKey: Utils.redisTipoArt, - expiration: TimeSpan.FromMinutes(redisLongTimeCache), + expiration: TimeSpan.FromSeconds(redisLongTimeCache), fetchFunc: async () => await dbController.AnagTipoArtLvAsync() ?? new List(), tagList: [Utils.redisTipoArt] ); @@ -244,7 +244,7 @@ namespace MP.SPEC.Data return await GetOrFetchAsync( operationName: "ArticleWithDossierAsync", cacheKey: Utils.redisArtByDossier, - expiration: TimeSpan.FromMinutes(redisLongTimeCache), + expiration: TimeSpan.FromSeconds(redisLongTimeCache), fetchFunc: async () => await Task.FromResult(dbController.ArticleWithDossier()) ?? new List(), tagList: [Utils.redisArtByDossier] ); @@ -302,7 +302,7 @@ namespace MP.SPEC.Data return await GetOrFetchAsync( operationName: "ArticoliGetSearchAsync", cacheKey: redisKey, - expiration: TimeSpan.FromMinutes(redisLongTimeCache), + expiration: TimeSpan.FromSeconds(redisLongTimeCache), fetchFunc: async () => await dbController.ArticoliGetSearchAsync(numRecord, tipoArt, azienda, searchVal) ?? new List(), tagList: [Utils.redisArtList, $"{Utils.redisArtList}:Search"] @@ -422,7 +422,7 @@ namespace MP.SPEC.Data return await GetOrFetchAsync( operationName: "ConfigGetAllAsync", cacheKey: Utils.redisConfKey, - expiration: TimeSpan.FromMinutes(redisLongTimeCache), + expiration: TimeSpan.FromSeconds(redisLongTimeCache), fetchFunc: async () => await dbController.ConfigGetAllAsync() ?? new List(), tagList: [Utils.redisConfKey] ); @@ -676,7 +676,7 @@ namespace MP.SPEC.Data return await GetOrFetchAsync( operationName: "ElencoLinkAsync", cacheKey: Utils.redisLinkMenu, - expiration: TimeSpan.FromMinutes(redisLongTimeCache), + expiration: TimeSpan.FromSeconds(redisLongTimeCache), fetchFunc: async () => await dbController.ElencoLinkAsync() ?? new List(), tagList: [Utils.redisLinkMenu] ); @@ -1111,7 +1111,7 @@ namespace MP.SPEC.Data return await GetOrFetchAsync( operationName: "FluxLogParetoAsync", cacheKey: redKey, - expiration: TimeSpan.FromMinutes(redisLongTimeCache), + expiration: TimeSpan.FromSeconds(redisLongTimeCache), fetchFunc: async () => await dbController.FluxLogParetoAsync(idxMacchina, dtFrom, dtTo) ?? new List(), tagList: [Utils.redisParetoFLKey] ); @@ -1257,7 +1257,7 @@ namespace MP.SPEC.Data return await GetOrFetchAsync( operationName: "IstKitFiltAsync", cacheKey: currKey, - expiration: TimeSpan.FromMinutes(redisLongTimeCache), + expiration: TimeSpan.FromSeconds(redisLongTimeCache), fetchFunc: async () => await dbController.IstKitFiltAsync(keyKit, keyExtOrd) ?? new List(), tagList: [Utils.redisKitInst] ); @@ -1513,7 +1513,7 @@ namespace MP.SPEC.Data return await GetOrFetchAsync( operationName: "MacchineWithFluxAsync", cacheKey: currKey, - expiration: TimeSpan.FromMinutes(redisLongTimeCache), + expiration: TimeSpan.FromSeconds(redisLongTimeCache), fetchFunc: async () => await dbController.MacchineWithFluxAsync(dtStart, dtEnd) ?? new List(), tagList: [Utils.redisMacByFlux] ); @@ -1946,16 +1946,16 @@ namespace MP.SPEC.Data /// /// /// - public PODLModel POdlGetByOdl(int idxODL) + public async Task POdlGetByOdlAsync(int idxODL) { PODLModel result = new PODLModel(); if (idxODL != 0) { - using var activity = ActivitySource.StartActivity("POdlGetByOdl"); + using var activity = ActivitySource.StartActivity("POdlGetByOdlAsync"); string source = "DB"; string currKey = $"{Utils.redisPOdlByOdl}:{idxODL}"; // cerco in redis dato valore sel idxMaccSel... - RedisValue rawData = redisDb.StringGet(currKey); + RedisValue rawData = await redisDb.StringGetAsync(currKey); if (rawData.HasValue) { var rawResult = JsonConvert.DeserializeObject($"{rawData}"); @@ -1967,10 +1967,10 @@ namespace MP.SPEC.Data } else { - result = dbController.PODL_getByOdl(idxODL); + result = await dbController.PODL_getByOdlAsync(idxODL); // serializzo e salvo... rawData = JsonConvert.SerializeObject(result); - redisDb.StringSet(currKey, rawData, getRandTOut(redisLongTimeCache)); + await redisDb.StringSetAsync(currKey, rawData, getRandTOut(redisLongTimeCache)); } if (result == null) { @@ -1979,7 +1979,7 @@ namespace MP.SPEC.Data activity?.SetTag("data.source", source); activity?.SetTag("result.count", 1); activity?.Stop(); - Log.Trace($"POdlGetByOdl | Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); + Log.Trace($"POdlGetByOdlAsync | Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); } else { @@ -2054,47 +2054,6 @@ namespace MP.SPEC.Data /// Data inizio /// Data fine /// - public List POdlListGetFilt(bool lanciato, string keyRichPart, string idxMacchina, string codGruppo, DateTime startDate, DateTime endDate) - { - using var activity = ActivitySource.StartActivity("POdlListGetFiltAsync"); - List? result = new List(); - string source = "DB"; - string currKey = $"{Utils.redisPOdlList}:{codGruppo}:{idxMacchina}:{keyRichPart}:{lanciato}:{startDate:yyyyMMdd_HHmmss}:{endDate:yyyyMMdd_HHmmss}"; - // cerco in redis dato valore sel idxMaccSel... - RedisValue rawData = redisDb.StringGet(currKey); - if (rawData.HasValue) - { - result = JsonConvert.DeserializeObject>($"{rawData}"); - source = "REDIS"; - } - else - { - result = dbController.ListPODLFilt(lanciato, keyRichPart, idxMacchina, codGruppo, startDate, endDate); - // serializzo e salvo... - rawData = JsonConvert.SerializeObject(result); - redisDb.StringSet(currKey, rawData, TimeSpan.FromSeconds(redisShortTimeCache)); - } - if (result == null) - { - result = new List(); - } - activity?.SetTag("data.source", source); - activity?.SetTag("result.count", result.Count); - activity?.Stop(); - LogTrace($"POdlListGetFilt | Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); - return result; - } - - /// - /// Elenco PODL (Async) non avviati filtrati x articolo, KeyRich (che contiene stato) - /// - /// Solo lanciati (1) o ancora disponibili (0) - /// KeyRich (parziale) da cercare (es cod stato x yacht) - /// Macchina - /// Gruppo - /// Data inizio - /// Data fine - /// public async Task> POdlListGetFiltAsync(bool lanciato, string keyRichPart, string idxMacchina, string codGruppo, DateTime startDate, DateTime endDate) { string currKey = $"{Utils.redisPOdlList}:{codGruppo}:{idxMacchina}:{keyRichPart}:{lanciato}:{startDate:yyyyMMdd_HHmmss}:{endDate:yyyyMMdd_HHmmss}"; @@ -2122,20 +2081,20 @@ namespace MP.SPEC.Data string redisKey = $"{Utils.redisPOdlList}_kit:{codGruppo}:{idxMacchina}:{keyRichPart}:{lanciato}:{startDate:yyyyMMdd_HHmmss}:{endDate:yyyyMMdd_HHmmss}"; return await GetOrFetchAsync( - operationName: "POdlToKitListGetFiltAsync", - cacheKey: redisKey, - expiration: TimeSpan.FromSeconds(redisShortTimeCache * 5), - fetchFunc: async () => - await dbController.ListPODL_KitFiltAsync( - lanciato, - keyRichPart, - idxMacchina, - codGruppo, - startDate, - endDate - ) ?? new List(), - tagList: [Utils.redisPOdlList, $"{Utils.redisPOdlList}_kit"] - ); + operationName: "POdlToKitListGetFiltAsync", + cacheKey: redisKey, + expiration: TimeSpan.FromSeconds(redisShortTimeCache * 5), + fetchFunc: async () => + await dbController.ListPODL_KitFiltAsync( + lanciato, + keyRichPart, + idxMacchina, + codGruppo, + startDate, + endDate + ) ?? new List(), + tagList: [Utils.redisPOdlList, $"{Utils.redisPOdlList}_kit"] + ); } /// @@ -2410,7 +2369,7 @@ namespace MP.SPEC.Data var result = await GetOrFetchAsync( operationName: "TemplateKitFiltAsync", cacheKey: currKey, - expiration: TimeSpan.FromMinutes(redisLongTimeCache), + expiration: TimeSpan.FromSeconds(redisLongTimeCache), fetchFunc: async () => await dbController.TemplateKitFiltAsync(codParent, codChild) ?? new List(), tagList: [Utils.redisKitTempl] ); @@ -2468,7 +2427,7 @@ namespace MP.SPEC.Data result = await dbController.TksScoreAsync(KeyFilt, MaxResult); // serializzo e salvo... rawData = JsonConvert.SerializeObject(result); - await redisDb.StringSetAsync(currKey, rawData, TimeSpan.FromMinutes(redisLongTimeCache)); + await redisDb.StringSetAsync(currKey, rawData, TimeSpan.FromSeconds(redisLongTimeCache)); } if (result == null) { @@ -2599,7 +2558,7 @@ namespace MP.SPEC.Data result = await dbController.WipKitFiltAsync(KeyFilt); // serializzo e salvo... rawData = JsonConvert.SerializeObject(result); - await redisDb.StringSetAsync(currKey, rawData, TimeSpan.FromMinutes(redisLongTimeCache)); + await redisDb.StringSetAsync(currKey, rawData, TimeSpan.FromSeconds(redisLongTimeCache)); } if (result == null) { @@ -2636,14 +2595,14 @@ namespace MP.SPEC.Data #region Protected Methods /// - /// Restituisce un timeout dai minuti richiesti + tempo random -15..+15 sec + /// Restituisce un timeout dal valore secondi richiesti + tempo random -10..+10 sec /// - /// + /// /// - protected TimeSpan getRandTOut(double stdMinutes) + protected TimeSpan getRandTOut(double durationSec) { - double rndValue = stdMinutes + (double)rand.Next(-15, 15) / 60; - return TimeSpan.FromMinutes(rndValue); + double rndValue = durationSec + (double)rand.Next(-5, 5); + return TimeSpan.FromSeconds(rndValue); } /// @@ -2758,9 +2717,15 @@ namespace MP.SPEC.Data /// private IDatabase redisDb = null!; + /// + /// Durata cache breve standard (5 sec) + /// private int redisLongTimeCache = 5; - private int redisShortTimeCache = 2; + /// + /// Durata cache long standard (5min) + /// + private int redisShortTimeCache = 300; private bool traceEnabled = false; diff --git a/MP.SPEC/MP.SPEC.csproj b/MP.SPEC/MP.SPEC.csproj index 8f6e41c9..3b9749c9 100644 --- a/MP.SPEC/MP.SPEC.csproj +++ b/MP.SPEC/MP.SPEC.csproj @@ -5,7 +5,7 @@ enable enable MP.SPEC - 8.16.2605.2811 + 8.16.2605.2812 1800a78a-6ff1-40f9-b490-87fb8bfc1394 en diff --git a/MP.SPEC/Resources/ChangeLog.html b/MP.SPEC/Resources/ChangeLog.html index 9b69bf46..c2315960 100644 --- a/MP.SPEC/Resources/ChangeLog.html +++ b/MP.SPEC/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MAPOSPEC -

Versione: 8.16.2605.2811

+

Versione: 8.16.2605.2812


Note di rilascio:
  • diff --git a/MP.SPEC/Resources/VersNum.txt b/MP.SPEC/Resources/VersNum.txt index 378864b8..5f877377 100644 --- a/MP.SPEC/Resources/VersNum.txt +++ b/MP.SPEC/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2605.2811 +8.16.2605.2812 diff --git a/MP.SPEC/Resources/manifest.xml b/MP.SPEC/Resources/manifest.xml index d3e3fe22..82abe1dc 100644 --- a/MP.SPEC/Resources/manifest.xml +++ b/MP.SPEC/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2605.2811 + 8.16.2605.2812 https://nexus.steamware.net/repository/SWS/MP-SPEC/stable/LAST/MP.SPEC.zip https://nexus.steamware.net/repository/SWS/MP-SPEC/stable/LAST/ChangeLog.html false