From 59b49084f9d6a5a7ec1f80bd467e0c29bbaf691a Mon Sep 17 00:00:00 2001 From: "Samuele E. Locatelli (W11-AI)" Date: Fri, 17 Apr 2026 18:29:55 +0200 Subject: [PATCH] Moproposte x ottimizzare input (da testare) --- MP.IOC/Data/MpDataService.cs | 142 ++++++++++++++++++++++++++++++++--- 1 file changed, 133 insertions(+), 9 deletions(-) diff --git a/MP.IOC/Data/MpDataService.cs b/MP.IOC/Data/MpDataService.cs index 62e209a8..b4b77b69 100644 --- a/MP.IOC/Data/MpDataService.cs +++ b/MP.IOC/Data/MpDataService.cs @@ -1,4 +1,4 @@ -using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore; using MP.Core.Conf; using MP.Core.DTO; using MP.Core.Objects; @@ -561,11 +561,12 @@ namespace MP.IOC.Data /// valore ingresso /// data-ora evento (server) /// sequenza dati inviati + /// dati macchina in cache (opzionale, se null fa lookup) /// - public async Task CheckMicroStatoAsync(string idxMacchina, string valore, DateTime dtEve, string contatore) + public async Task CheckMicroStatoAsync(string idxMacchina, string valore, DateTime dtEve, string contatore, Dictionary? datiMaccCache = null) { // recupero SE IMPIEGATO REDIS i valori del Dictionary della macchina... - Dictionary datiMacc = await mDatiMacchineAsync(idxMacchina); + Dictionary datiMacc = datiMaccCache ?? await mDatiMacchineAsync(idxMacchina); // processing inputComandoMapo answ = new inputComandoMapo(); @@ -2025,6 +2026,31 @@ namespace MP.IOC.Data return answ; } + /// + /// Restitusice elenco KVP (async) per evitare blocchi quando chiamato da metodi asincroni + /// + /// + /// + public async Task[]> mTabMSMIAsync(string idxMacchina) + { + KeyValuePair[] answ = new KeyValuePair[1]; + answ[0] = new KeyValuePair("0", "0"); + try + { + var currHash = Utils.RedKeyMsmi(idxMacchina); + answ = await RedisGetHashDictAsync(currHash); + if (answ == null || answ.Length == 0) + { + answ = await resetMSMIAsync(idxMacchina); + } + } + catch (Exception exc) + { + Log.Error($"Errore in compilazione Tabella Multi State Machine Ingressi x Redis:{Environment.NewLine}{exc}"); + } + return answ; + } + /// /// Restitusice elenco KVP dei TASK (da passare a IOB-WIN) per l'impianto indicato /// @@ -2714,26 +2740,28 @@ namespace MP.IOC.Data { // scrivo keep alive!!! (se necessario, altrimenti è in cache...) await ScriviKeepAliveAsync(idxMacchina, DateTime.Now); + // Cache dati macchina per evitare lookup ridondanti + Dictionary datiMacc = await mDatiMacchineAsync(idxMacchina); // verifico se sia una macchina MULTI ed in tal caso calcolo i // SUB-systems e CHIAMERO' alla fine pure loro.... - if (isMulti(idxMacchina)) + if (isMulti(idxMacchina, datiMacc)) { // inizio preprocessing string newVal = ""; // processo OGNI macchina a stati dell'impianto... (KEY:IdxMacchina / IdxMacchina#qualcosa, Val = IdxFamIn) - foreach (var item in mTabMSMI(idxMacchina)) + foreach (var item in await mTabMSMIAsync(idxMacchina)) { - newVal = preProcInput(item.Key, valore); + newVal = preProcInput(item.Key, valore, datiMacc); // ora processo e salvo il valore del microstato... // INTERNAMENTE gestisce i casi DB/REDIS secondo necessità - await CheckMicroStatoAsync(item.Key, newVal, dataOraEvento, contatore); + await CheckMicroStatoAsync(item.Key, newVal, dataOraEvento, contatore, datiMacc); } } else { // ora processo e salvo il valore del microstato... INTERNAMENTE // gestisce i casi DB/REDIS secondo necessità - await CheckMicroStatoAsync(idxMacchina, valore, dataOraEvento, contatore); + await CheckMicroStatoAsync(idxMacchina, valore, dataOraEvento, contatore, datiMacc); } // registro in risposta che è andato tutto bene... answ = "OK"; @@ -3391,6 +3419,32 @@ namespace MP.IOC.Data return answ; } + /// + /// + public async Task[]> resetMSMIAsync(string idxMacchina) + { + var currHash = Utils.RedKeyMsmi(idxMacchina); + // recupero records + var tabMSMI = await IocDbController.VMSFDGetMultiByMaccAsync(idxMacchina); + + KeyValuePair[] answ = new KeyValuePair[tabMSMI.Count]; + // salvo tutti i valori StateMachineIngressi... + int i = 0; + foreach (var item in tabMSMI) + { + answ[i] = new KeyValuePair(item.IdxMacchina, item.IdxFamigliaIngresso.ToString()); + i++; + } + // verifico il timeout (default 60 sec...) + var sTOutSmi = await tryGetConfig("TmOut.MSMI"); + int tOut = 60; + int.TryParse(sTOutSmi, out tOut); + tOut = tOut <= 60 ? 60 : tOut; + // salvo in redis! + await RedisSetHashAsync(currHash, answ, tOut); + return answ; + } + /// /// Processa registrazione EVENTO CONTEGGIO PEZZI x una data macchina IOB /// @@ -4340,6 +4394,27 @@ namespace MP.IOC.Data return answ; } + /// + /// Restituisce il valore booleano se la macchina sia di tipo MULTI (con più state machine x INGRESSI) + /// usando dati macchina in cache per evitare lookup ridondanti + /// + /// + /// + /// + private bool isMulti(string idxMacchina, Dictionary datiMacc) + { + bool answ = false; + try + { + answ = Convert.ToBoolean(datiMacc.ContainsKey("Multi") && datiMacc["Multi"] == "1"); + } + catch (Exception exc) + { + Log.Error($"Eccezione in isMulti{Environment.NewLine}{exc}"); + } + return answ; + } + private async Task POdlFlushCache() { bool answ = false; @@ -4378,7 +4453,56 @@ namespace MP.IOC.Data int.TryParse(mDatiMacchinaVal(idxMacchina, "BSR"), out BSR); Boolean.TryParse(mDatiMacchinaVal(idxMacchina, "ExplodeBit"), out ExplodeBit); int.TryParse(mDatiMacchinaVal(idxMacchina, "NumBit"), out NumBit); // non usato (x ora) - // recupero valore + // recupero valore + valINT = int.Parse(valore, NumberStyles.HexNumber); + // filtro + newValInt = MP.Core.Utils.bMaskInt(valINT, BitFilt); + // effettuo eventuale BitShiftRight + if (BSR > 0) + { + newValInt = newValInt >> BSR; + } + // effettuo eventuale esplosione in BIT esclusivi + if (ExplodeBit) + { + newValInt = Convert.ToInt32(1 << newValInt); + } + // riconverto a STRING HEX!!! + newVal = newValInt.ToString("X"); + } + catch + { + newVal = valore; + } + + return newVal; + } + + /// + /// Calcola l'effettivo valore da passare alla macchina a stati INGRESSI usando dati macchina in cache + /// + /// + /// + /// + /// + private string preProcInput(string idxMacchina, string valore, Dictionary datiMacc) + { + string newVal = ""; + try + { + // variabili + int valINT = 0; + int BitFilt = 0; + int BSR = 0; + bool ExplodeBit = false; + int NumBit = 0; + int newValInt = 0; + // recupero parametri dalla cache... + int.TryParse(datiMacc.ContainsKey("BitFilt") ? datiMacc["BitFilt"] : "0", out BitFilt); + int.TryParse(datiMacc.ContainsKey("BSR") ? datiMacc["BSR"] : "0", out BSR); + Boolean.TryParse(datiMacc.ContainsKey("ExplodeBit") ? datiMacc["ExplodeBit"] : "false", out ExplodeBit); + int.TryParse(datiMacc.ContainsKey("NumBit") ? datiMacc["NumBit"] : "0", out NumBit); // non usato (x ora) + // recupero valore valINT = int.Parse(valore, NumberStyles.HexNumber); // filtro newValInt = MP.Core.Utils.bMaskInt(valINT, BitFilt);