From 7ca5637fe476c63fee2d9e480ec01edd2c6d9cc4 Mon Sep 17 00:00:00 2001 From: Samuele Locatelli Date: Wed, 6 May 2026 07:15:57 +0200 Subject: [PATCH 1/4] Aggiunta InMemoryCache x servizi legati a INPUT (es list master/slave) --- MP.Data/Services/IOC/IocService.cs | 25 ++++++++++++++++++++++--- MP.IOC/MP.IOC.csproj | 2 +- MP.IOC/Resources/ChangeLog.html | 2 +- MP.IOC/Resources/VersNum.txt | 2 +- MP.IOC/Resources/manifest.xml | 2 +- 5 files changed, 26 insertions(+), 7 deletions(-) diff --git a/MP.Data/Services/IOC/IocService.cs b/MP.Data/Services/IOC/IocService.cs index 8c5b9407..f8b03f89 100644 --- a/MP.Data/Services/IOC/IocService.cs +++ b/MP.Data/Services/IOC/IocService.cs @@ -1,4 +1,5 @@ -using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.Caching.Memory; +using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using MP.Core.Objects; using MP.Data.DbModels; @@ -23,13 +24,15 @@ namespace MP.Data.Services.IOC IConfiguration config, IConnectionMultiplexer redis, IIocRepository repo, - IServiceScopeFactory scopeFactory) : base(config, redis) + IServiceScopeFactory scopeFactory, + Microsoft.Extensions.Caching.Memory.IMemoryCache cache) : base(config, redis) { _className = "IocServ"; int.TryParse(config.GetValue("ServerConf:redisLongTimeCache"), out redisLongTimeCache); int.TryParse(config.GetValue("ServerConf:redisShortTimeCache"), out redisShortTimeCache); _repo = repo; _scopeFactory = scopeFactory; + _cache = cache; } #endregion Public Constructors @@ -176,8 +179,8 @@ namespace MP.Data.Services.IOC private readonly string _className; private readonly IIocRepository _repo; - private readonly IServiceScopeFactory _scopeFactory; + private readonly Microsoft.Extensions.Caching.Memory.IMemoryCache _cache; /// /// Provider CultureInfo x parse valori (es dataora) @@ -387,6 +390,12 @@ namespace MP.Data.Services.IOC private async Task> ListMasterAsync() { + const string cacheKey = "IOC_ListMaster"; + if (_cache.TryGetValue(cacheKey, out HashSet? cachedList)) + { + return cachedList!; + } + HashSet result = new(); string currKey = $"{MP.Data.Utils.redisBaseAddr}:ListMaster"; RedisValue rawData = await _redisDb.StringGetAsync(currKey); @@ -402,11 +411,19 @@ namespace MP.Data.Services.IOC rawData = JsonConvert.SerializeObject(result); await _redisDb.StringSetAsync(currKey, rawData, getRandTOut(redisLongTimeCache * 10)); } + + _cache.Set(cacheKey, result, TimeSpan.FromMinutes(5)); return result; } private async Task> ListSlaveAsync() { + const string cacheKey = "IOC_ListSlave"; + if (_cache.TryGetValue(cacheKey, out HashSet? cachedList)) + { + return cachedList!; + } + HashSet result = new(); string currKey = $"{MP.Data.Utils.redisBaseAddr}:ListSlave"; RedisValue rawData = await _redisDb.StringGetAsync(currKey); @@ -422,6 +439,8 @@ namespace MP.Data.Services.IOC rawData = JsonConvert.SerializeObject(result); await _redisDb.StringSetAsync(currKey, rawData, getRandTOut(redisLongTimeCache * 10)); } + + _cache.Set(cacheKey, result, TimeSpan.FromMinutes(5)); return result; } diff --git a/MP.IOC/MP.IOC.csproj b/MP.IOC/MP.IOC.csproj index 09b2a86c..b1c6362a 100644 --- a/MP.IOC/MP.IOC.csproj +++ b/MP.IOC/MP.IOC.csproj @@ -4,7 +4,7 @@ net8.0 enable enable - 8.16.2605.415 + 8.16.2605.607 diff --git a/MP.IOC/Resources/ChangeLog.html b/MP.IOC/Resources/ChangeLog.html index e967c5a4..7c872463 100644 --- a/MP.IOC/Resources/ChangeLog.html +++ b/MP.IOC/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MP-IOC -

Versione: 8.16.2605.415

+

Versione: 8.16.2605.607


Note di rilascio:
  • diff --git a/MP.IOC/Resources/VersNum.txt b/MP.IOC/Resources/VersNum.txt index c9e2711c..b78c4978 100644 --- a/MP.IOC/Resources/VersNum.txt +++ b/MP.IOC/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2605.415 +8.16.2605.607 diff --git a/MP.IOC/Resources/manifest.xml b/MP.IOC/Resources/manifest.xml index 39fb4c88..97a76db6 100644 --- a/MP.IOC/Resources/manifest.xml +++ b/MP.IOC/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2605.415 + 8.16.2605.607 https://nexus.steamware.net/repository/SWS/MP-IOC/stable/LAST/MP.IOC.zip https://nexus.steamware.net/repository/SWS/MP-IOC/stable/LAST/ChangeLog.html false From 2f108ebdd3689cb07491fbd95a6108f771b6d6b0 Mon Sep 17 00:00:00 2001 From: Samuele Locatelli Date: Wed, 6 May 2026 09:16:30 +0200 Subject: [PATCH 2/4] inizio inserimento InMemoryCache x metodi vari IOC --- MP.Data/Services/IOC/IocService.cs | 164 ++++++++++++++++------------ MP.IOC/Controllers/IOBController.cs | 3 +- MP.IOC/MP.IOC.csproj | 2 +- MP.IOC/Program.cs | 2 + MP.IOC/Resources/ChangeLog.html | 2 +- MP.IOC/Resources/VersNum.txt | 2 +- MP.IOC/Resources/manifest.xml | 2 +- 7 files changed, 101 insertions(+), 76 deletions(-) diff --git a/MP.Data/Services/IOC/IocService.cs b/MP.Data/Services/IOC/IocService.cs index f8b03f89..711b3da9 100644 --- a/MP.Data/Services/IOC/IocService.cs +++ b/MP.Data/Services/IOC/IocService.cs @@ -181,9 +181,10 @@ namespace MP.Data.Services.IOC private readonly IIocRepository _repo; private readonly IServiceScopeFactory _scopeFactory; private readonly Microsoft.Extensions.Caching.Memory.IMemoryCache _cache; + private readonly System.Threading.SemaphoreSlim _semaphore = new System.Threading.SemaphoreSlim(1, 1); /// - /// Provider CultureInfo x parse valori (es dataora) + /// Provider CultureInfo x parse valori(es dataora) /// private CultureInfo ciProvider = CultureInfo.InvariantCulture; @@ -297,32 +298,34 @@ namespace MP.Data.Services.IOC /// /// Elenco completo config da DB /// - /// private async Task> ConfigGetAllAsync() { - List? result = new List(); - // cerco in redis... - RedisValue rawData = await _redisDb.StringGetAsync(MP.Data.Utils.redisConfKey); - string source = "DB"; - if (!string.IsNullOrEmpty($"{rawData}")) + return await GetOrFetchAsync("IOC_ConfigAll", async () => { - result = JsonConvert.DeserializeObject>($"{rawData}"); - source = "REDIS"; - } - else - { - result = await _repo.ConfigGetAllAsync(); - //result = await Task.FromResult(SpecDbController.ConfigGetAllAsync()); - // serializzo e salvo... - rawData = JsonConvert.SerializeObject(result); - await _redisDb.StringSetAsync(MP.Data.Utils.redisConfKey, rawData, getRandTOut(redisLongTimeCache)); - } - Log.Debug($"ConfigGetAllAsync Read from {source}"); - if (result == null) - { - result = new List(); - } - return result; + List? result = new List(); + // cerco in redis... + RedisValue rawData = await _redisDb.StringGetAsync(MP.Data.Utils.redisConfKey); + string source = "DB"; + if (!string.IsNullOrEmpty($"{rawData}")) + { + result = JsonConvert.DeserializeObject>($"{rawData}"); + source = "REDIS"; + } + else + { + result = await _repo.ConfigGetAllAsync(); + //result = await Task.FromResult(SpecDbController.ConfigGetAllAsync()); + // serializzo e salvo... + rawData = JsonConvert.SerializeObject(result); + await _redisDb.StringSetAsync(MP.Data.Utils.redisConfKey, rawData, getRandTOut(redisLongTimeCache)); + } + Log.Debug($"ConfigGetAllAsync Read from {source}"); + if (result == null) + { + result = new List(); + } + return result; + }, TimeSpan.FromMinutes(10)); } /// @@ -388,60 +391,81 @@ namespace MP.Data.Services.IOC return answ; } + /// + /// Implementa gestione recupero cache da memoria o da obj esterno + cache memoria + /// + /// + /// + /// + /// + /// + private async Task GetOrFetchAsync(string cacheKey, Func> fetchFunc, TimeSpan expiration) + { + if (_cache.TryGetValue(cacheKey, out T? cachedValue)) + { + return cachedValue!; + } + + await _semaphore.WaitAsync(); + try + { + if (_cache.TryGetValue(cacheKey, out cachedValue)) + { + return cachedValue!; + } + + T newValue = await fetchFunc(); + _cache.Set(cacheKey, newValue, expiration); + return newValue; + } + finally + { + _semaphore.Release(); + } + } + private async Task> ListMasterAsync() { - const string cacheKey = "IOC_ListMaster"; - if (_cache.TryGetValue(cacheKey, out HashSet? cachedList)) + return await GetOrFetchAsync("IOC_ListMaster", async () => { - return cachedList!; - } - - HashSet result = new(); - string currKey = $"{MP.Data.Utils.redisBaseAddr}:ListMaster"; - RedisValue rawData = await _redisDb.StringGetAsync(currKey); - if (rawData.HasValue) - { - result = JsonConvert.DeserializeObject>($"{rawData}") ?? new(); - } - else - { - var fullList = await Macchine2SlaveGetAllAsync(); - result = fullList.Select(x => x.IdxMacchina).ToHashSet(); - // serializzo e salvo... - rawData = JsonConvert.SerializeObject(result); - await _redisDb.StringSetAsync(currKey, rawData, getRandTOut(redisLongTimeCache * 10)); - } - - _cache.Set(cacheKey, result, TimeSpan.FromMinutes(5)); - return result; + HashSet result = new(); + string currKey = $"{MP.Data.Utils.redisBaseAddr}:ListMaster"; + RedisValue rawData = await _redisDb.StringGetAsync(currKey); + if (rawData.HasValue) + { + result = JsonConvert.DeserializeObject>($"{rawData}") ?? new(); + } + else + { + var fullList = await Macchine2SlaveGetAllAsync(); + result = fullList.Select(x => x.IdxMacchina).ToHashSet(); + rawData = JsonConvert.SerializeObject(result); + await _redisDb.StringSetAsync(currKey, rawData, getRandTOut(redisLongTimeCache * 10)); + } + return result; + }, TimeSpan.FromMinutes(5)); } private async Task> ListSlaveAsync() { - const string cacheKey = "IOC_ListSlave"; - if (_cache.TryGetValue(cacheKey, out HashSet? cachedList)) + return await GetOrFetchAsync("IOC_ListSlave", async () => { - return cachedList!; - } - - HashSet result = new(); - string currKey = $"{MP.Data.Utils.redisBaseAddr}:ListSlave"; - RedisValue rawData = await _redisDb.StringGetAsync(currKey); - if (rawData.HasValue) - { - result = JsonConvert.DeserializeObject>($"{rawData}") ?? new(); - } - else - { - var fullList = await Macchine2SlaveGetAllAsync(); - result = fullList.Select(x => x.IdxMacchinaSlave).Distinct().ToHashSet(); - // serializzo e salvo... - rawData = JsonConvert.SerializeObject(result); - await _redisDb.StringSetAsync(currKey, rawData, getRandTOut(redisLongTimeCache * 10)); - } - - _cache.Set(cacheKey, result, TimeSpan.FromMinutes(5)); - return result; + HashSet result = new(); + string currKey = $"{MP.Data.Utils.redisBaseAddr}:ListSlave"; + RedisValue rawData = await _redisDb.StringGetAsync(currKey); + if (rawData.HasValue) + { + result = JsonConvert.DeserializeObject>($"{rawData}") ?? new(); + } + else + { + var fullList = await Macchine2SlaveGetAllAsync(); + result = fullList.Select(x => x.IdxMacchinaSlave).Distinct().ToHashSet(); + rawData = JsonConvert.SerializeObject(result); + await _redisDb.StringSetAsync(currKey, rawData, getRandTOut(redisLongTimeCache * 10)); + } + return result; + }, TimeSpan.FromMinutes(5)); } /// diff --git a/MP.IOC/Controllers/IOBController.cs b/MP.IOC/Controllers/IOBController.cs index 7df179a4..b30d13ce 100644 --- a/MP.IOC/Controllers/IOBController.cs +++ b/MP.IOC/Controllers/IOBController.cs @@ -70,7 +70,7 @@ namespace MP.IOC.Controllers } catch (Exception exc) { - Log.Error($"Errore in GetTask2Exe{Environment.NewLine}{exc}"); + Log.Error($"Errore in AddTask2Exe{Environment.NewLine}{exc}"); return StatusCode(StatusCodes.Status500InternalServerError, "NO"); } return Ok(answ); @@ -100,7 +100,6 @@ namespace MP.IOC.Controllers { // Il metodo ora restituisce direttamente il booleano logico bool isEnabled = await IOCService.IobInsEnabAsync(id); - //bool isEnabled = await DService.IobInsEnabAsync(id); return isEnabled ? Ok("OK") diff --git a/MP.IOC/MP.IOC.csproj b/MP.IOC/MP.IOC.csproj index b1c6362a..f2baf173 100644 --- a/MP.IOC/MP.IOC.csproj +++ b/MP.IOC/MP.IOC.csproj @@ -4,7 +4,7 @@ net8.0 enable enable - 8.16.2605.607 + 8.16.2605.609 diff --git a/MP.IOC/Program.cs b/MP.IOC/Program.cs index 207578c7..c0ccbfda 100644 --- a/MP.IOC/Program.cs +++ b/MP.IOC/Program.cs @@ -67,6 +67,8 @@ logger.Info("RedisScript Provider configured"); var connStr = builder.Configuration.GetConnectionString("MP.Data") ?? throw new InvalidOperationException("ConnString 'MP.Data' mancante."); +builder.Services.AddMemoryCache(); + builder.Services.AddDbContextFactory(options => options.UseSqlServer(connStr) .EnableSensitiveDataLogging(false) // true solo in Sviluppo diff --git a/MP.IOC/Resources/ChangeLog.html b/MP.IOC/Resources/ChangeLog.html index 7c872463..8e8d8134 100644 --- a/MP.IOC/Resources/ChangeLog.html +++ b/MP.IOC/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MP-IOC -

    Versione: 8.16.2605.607

    +

    Versione: 8.16.2605.609


    Note di rilascio:
    • diff --git a/MP.IOC/Resources/VersNum.txt b/MP.IOC/Resources/VersNum.txt index b78c4978..0a727783 100644 --- a/MP.IOC/Resources/VersNum.txt +++ b/MP.IOC/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2605.607 +8.16.2605.609 diff --git a/MP.IOC/Resources/manifest.xml b/MP.IOC/Resources/manifest.xml index 97a76db6..0498bfc7 100644 --- a/MP.IOC/Resources/manifest.xml +++ b/MP.IOC/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2605.607 + 8.16.2605.609 https://nexus.steamware.net/repository/SWS/MP-IOC/stable/LAST/MP.IOC.zip https://nexus.steamware.net/repository/SWS/MP-IOC/stable/LAST/ChangeLog.html false From 0e6abf4f28ad3545492916b1800d90f36c92bb90 Mon Sep 17 00:00:00 2001 From: Samuele Locatelli Date: Wed, 6 May 2026 09:47:56 +0200 Subject: [PATCH 3/4] Implementata cache in memoria per alcuni metodi "di configurazione long period" --- MP.Data/Services/IOC/IocService.cs | 131 +++++++++++++++-------------- 1 file changed, 69 insertions(+), 62 deletions(-) diff --git a/MP.Data/Services/IOC/IocService.cs b/MP.Data/Services/IOC/IocService.cs index 711b3da9..7d9fed11 100644 --- a/MP.Data/Services/IOC/IocService.cs +++ b/MP.Data/Services/IOC/IocService.cs @@ -56,17 +56,21 @@ namespace MP.Data.Services.IOC /// public async Task IobInsEnabAsync(string idxMacchina) { - var key = MP.Data.Utils.RedKeyDatiMacc(idxMacchina, MpIoNS); - - string? val = await _redisDb.HashGetAsync(key, "insEnabled"); - - if (val == null) + string cacheKey = $"IOC_IobInsEnab_{idxMacchina}"; + return await GetOrFetchAsync(cacheKey, async () => { - var data = await ResetDatiMacchinaAsync(idxMacchina); - data.TryGetValue("insEnabled", out val); - } + var key = MP.Data.Utils.RedKeyDatiMacc(idxMacchina, MpIoNS); - return val != null && (val == "1" || val.ToLower() == "true"); + string? val = await _redisDb.HashGetAsync(key, "insEnabled"); + + if (val == null) + { + var data = await ResetDatiMacchinaAsync(idxMacchina); + data.TryGetValue("insEnabled", out val); + } + + return val != null && (val == "1" || val.ToLower() == "true"); + }, TimeSpan.FromSeconds(5)); } /// @@ -176,11 +180,11 @@ namespace MP.Data.Services.IOC private static Logger Log = LogManager.GetCurrentClassLogger(); + private readonly Microsoft.Extensions.Caching.Memory.IMemoryCache _cache; private readonly string _className; private readonly IIocRepository _repo; private readonly IServiceScopeFactory _scopeFactory; - private readonly Microsoft.Extensions.Caching.Memory.IMemoryCache _cache; private readonly System.Threading.SemaphoreSlim _semaphore = new System.Threading.SemaphoreSlim(1, 1); /// @@ -338,6 +342,39 @@ namespace MP.Data.Services.IOC return s?.Length > 17 ? s[..17] : s?.PadRight(17, '0') ?? string.Empty; } + /// + /// Implementa gestione recupero cache da memoria o da obj esterno + cache memoria + /// + /// + /// + /// + /// + /// + private async Task GetOrFetchAsync(string cacheKey, Func> fetchFunc, TimeSpan expiration) + { + if (_cache.TryGetValue(cacheKey, out T? cachedValue)) + { + return cachedValue!; + } + + await _semaphore.WaitAsync(); + try + { + if (_cache.TryGetValue(cacheKey, out cachedValue)) + { + return cachedValue!; + } + + T newValue = await fetchFunc(); + _cache.Set(cacheKey, newValue, expiration); + return newValue; + } + finally + { + _semaphore.Release(); + } + } + /// /// Restituisce il valOut booleano se la macchina sia abilitata all'inserimento COMPLETO nel /// Signal Log @@ -391,39 +428,6 @@ namespace MP.Data.Services.IOC return answ; } - /// - /// Implementa gestione recupero cache da memoria o da obj esterno + cache memoria - /// - /// - /// - /// - /// - /// - private async Task GetOrFetchAsync(string cacheKey, Func> fetchFunc, TimeSpan expiration) - { - if (_cache.TryGetValue(cacheKey, out T? cachedValue)) - { - return cachedValue!; - } - - await _semaphore.WaitAsync(); - try - { - if (_cache.TryGetValue(cacheKey, out cachedValue)) - { - return cachedValue!; - } - - T newValue = await fetchFunc(); - _cache.Set(cacheKey, newValue, expiration); - return newValue; - } - finally - { - _semaphore.Release(); - } - } - private async Task> ListMasterAsync() { return await GetOrFetchAsync("IOC_ListMaster", async () => @@ -474,26 +478,29 @@ namespace MP.Data.Services.IOC /// private async Task> Macchine2SlaveGetAllAsync() { - List? result = new List(); - string currKey = $"{MP.Data.Utils.redisBaseAddr}:M2STab"; - // cerco in redis dato valOut sel macchina... - RedisValue rawData = await _redisDb.StringGetAsync(currKey); - if (rawData.HasValue) + return await GetOrFetchAsync("IOC_M2SlaveGetAll", async () => { - result = JsonConvert.DeserializeObject>($"{rawData}"); - } - else - { - result = await _repo.Macchine2SlaveAsync(); - // serializzo e salvo... - rawData = JsonConvert.SerializeObject(result); - await _redisDb.StringSetAsync(currKey, rawData, getRandTOut(redisLongTimeCache * 10)); - } - if (result == null) - { - result = new List(); - } - return result; + List? result = new List(); + string currKey = $"{MP.Data.Utils.redisBaseAddr}:M2STab"; + // cerco in redis dato valOut sel macchina... + RedisValue rawData = await _redisDb.StringGetAsync(currKey); + if (rawData.HasValue) + { + result = JsonConvert.DeserializeObject>($"{rawData}"); + } + else + { + result = await _repo.Macchine2SlaveAsync(); + // serializzo e salvo... + rawData = JsonConvert.SerializeObject(result); + await _redisDb.StringSetAsync(currKey, rawData, getRandTOut(redisLongTimeCache * 10)); + } + if (result == null) + { + result = new List(); + } + return result; + }, TimeSpan.FromMinutes(15)); } /// From 5dab9100da31d97056d9aa25c4eb1efc49b846ca Mon Sep 17 00:00:00 2001 From: Samuele Locatelli Date: Wed, 6 May 2026 10:08:09 +0200 Subject: [PATCH 4/4] Ulteriore ottimizzazione codice IOC x caching in memoria e obj scoped (da testare...) --- MP.Data/Repository/IOC/IIocRepository.cs | 8 ++ MP.Data/Repository/IOC/IocRepository.cs | 17 +++ MP.Data/Services/IOC/IIocService.cs | 31 +++++ MP.Data/Services/IOC/IocService.cs | 146 ++++++++++++++++++++++- MP.IOC/Controllers/IOBController.cs | 15 ++- MP.IOC/Data/MpDataService.cs | 8 +- MP.IOC/MP.IOC.csproj | 2 +- MP.IOC/Resources/ChangeLog.html | 2 +- MP.IOC/Resources/VersNum.txt | 2 +- MP.IOC/Resources/manifest.xml | 2 +- 10 files changed, 217 insertions(+), 16 deletions(-) diff --git a/MP.Data/Repository/IOC/IIocRepository.cs b/MP.Data/Repository/IOC/IIocRepository.cs index cfa5824f..19ad3f4a 100644 --- a/MP.Data/Repository/IOC/IIocRepository.cs +++ b/MP.Data/Repository/IOC/IIocRepository.cs @@ -102,6 +102,14 @@ namespace MP.Data.Repository.IOC /// Task> StateMachineIngressiAsync(int idxFam); + /// + /// Stato prod macchina (completo) Async + /// + /// + /// + /// + Task StatoProdMacchinaAsync(string idxMacchina, DateTime dtReq); + /// /// Vista v_MSFD x singola macchina (da stored) - singolo record /// diff --git a/MP.Data/Repository/IOC/IocRepository.cs b/MP.Data/Repository/IOC/IocRepository.cs index de11638e..2a13858d 100644 --- a/MP.Data/Repository/IOC/IocRepository.cs +++ b/MP.Data/Repository/IOC/IocRepository.cs @@ -316,6 +316,23 @@ namespace MP.Data.Repository.IOC return dbResult; } + /// + public async Task StatoProdMacchinaAsync(string idxMacchina, DateTime dtReq) + { + await using var dbCtx = await CreateContextAsync(); + + var IdxMacchina = new SqlParameter("@IdxMacchina", idxMacchina); + var DataOra = new SqlParameter("@DataOra ", dtReq); + var dbResult = (await dbCtx + .DbSetStatoProd + .FromSqlRaw("EXEC stp_StatoProd_getByMacchina @IdxMacchina, @DataOra ", IdxMacchina, DataOra) + .AsNoTracking() + .ToListAsync()) + .FirstOrDefault(); + + return dbResult; + } + /// public async Task VMSFDGetByMaccAsync(string idxMacc) { diff --git a/MP.Data/Services/IOC/IIocService.cs b/MP.Data/Services/IOC/IIocService.cs index 3f3b48a0..8e7f6a76 100644 --- a/MP.Data/Services/IOC/IIocService.cs +++ b/MP.Data/Services/IOC/IIocService.cs @@ -1,5 +1,6 @@ using MP.Data.DbModels; using System; +using System.Collections.Generic; using System.Threading.Tasks; using static MP.Core.Objects.Enums; @@ -31,6 +32,21 @@ namespace MP.Data.Services.IOC /// Task EvListMicroStatoInsertAsync(MicroStatoMacchinaModel newRecMsm, EventListModel newRecEv); + /// + /// Restituisce il valOut dell'ODL corrente (ODL deve esserci per gestione contapezzi, senza + /// ODL NO invio/gestione ODL) + /// + /// + /// + Task GetCurrOdlAsync(string idxMacchina); + + /// + /// Restitusice elenco KVP dei TASK (da passare a IOB-WIN) per l'impianto indicato + /// + /// + /// + Task> GetTask2ExeMacchinaAsync(string idxMacchina); + /// /// Restituisce il valOut booleano se la macchina sia abilitata all'input /// @@ -56,6 +72,21 @@ namespace MP.Data.Services.IOC /// Task ProcessInputAsync(string idxMacchina, string valore, string dtEve, string dtCurr, string contatore); + /// + /// Restituisce il contapezzi come CONTEGGIO da TCRilevati per la macchina - ASYNC + /// + /// + /// + Task PzCounterTcAsync(string idxMacchina); + + /// + /// Processa registrazione di un counter x una data macchina IOB + /// + /// + /// contapezzi + /// + Task SaveCounterAsync(string idxMacchina, string counter); + /// /// scrive un evento di keepalive sulla tabella /// diff --git a/MP.Data/Services/IOC/IocService.cs b/MP.Data/Services/IOC/IocService.cs index 7d9fed11..d4041c5f 100644 --- a/MP.Data/Services/IOC/IocService.cs +++ b/MP.Data/Services/IOC/IocService.cs @@ -53,6 +53,34 @@ namespace MP.Data.Services.IOC return success; } + /// + public async Task GetCurrOdlAsync(string idxMacchina) + { + string result = ""; + string currKey = $"{MP.Data.Utils.redisOdlCurrByMac}:{idxMacchina}"; + // cerco in redis dato valOut sel macchina... + RedisValue rawData = _redisDb.StringGet(currKey); + if (rawData.HasValue) + { + result = $"{rawData}"; + } + else + { + result = await GetCurrOdlByProdAsync(idxMacchina); + // serializzo e salvo... + rawData = JsonConvert.SerializeObject(result); + _redisDb.StringSet(currKey, rawData, getRandTOut(redisLongTimeCache)); + } + return result; + } + + /// + public async Task> GetTask2ExeMacchinaAsync(string idxMacchina) + { + var currHash = MP.Data.Utils.RedKeyTask2ExeMacc(idxMacchina, MpIoNS); + return await RedisGetHashDictAsync(currHash); + } + /// public async Task IobInsEnabAsync(string idxMacchina) { @@ -84,7 +112,7 @@ namespace MP.Data.Services.IOC public async Task ProcessInputAsync(string idxMacchina, string valore, string dtEve, string dtCurr, string contatore) { string answ = ""; - if (ValidateinputParams(idxMacchina, valore, dtEve, dtCurr)) + if (ValidateInputParams(idxMacchina, valore, dtEve, dtCurr)) { DateTime dataOraEvento = ParseEventTime(dtEve, dtCurr); @@ -137,6 +165,66 @@ namespace MP.Data.Services.IOC return answ; } + /// + public async Task PzCounterTcAsync(string idxMacchina) + { + int answ = -1; + DateTime dataRif = DateTime.Now; + var datiProd = await StatoProdMacchinaAsync(idxMacchina, dataRif); + if (datiProd != null) + { + answ = datiProd.PzTotODL; + } + return answ; + } + + /// + public async Task SaveCounterAsync(string idxMacchina, string counter) + { + string answ = "0"; + // inizio processing vero e proprio INPUT... + if (string.IsNullOrEmpty(idxMacchina)) + { + string errore = "Errore: parametro macchina vuoto"; + Log.Warn(errore); + answ = errore; + } + else + { + if (string.IsNullOrEmpty(counter)) + { + string errore = "Errore: parametro counter vuoto"; + Log.Warn(errore); + answ = errore; + } + else + { + int newCounter = -1; + int.TryParse(counter, out newCounter); + // se il conteggio è >= 0 SALVO come nuovo conteggio... + if (newCounter >= 0) + { + var currKey = MP.Data.Utils.RedKeyPzCount(idxMacchina, MpIoNS); + RedisValue rawData = await _redisDb.StringGetAsync(currKey); + if (rawData.HasValue) + { + // salvo per + tempo... + await _redisDb.StringSetAsync(currKey, answ.ToString()); + answ = counter; + } + else + { + int currCount = await PzCounterTcAsync(idxMacchina); + answ = currCount.ToString(); + // salvo per meno tempo... + await _redisDb.StringSetAsync(currKey, answ); + } + } + } + } + return answ; + } + /// public async Task ScriviKeepAliveAsync(string IdxMacchina, DateTime oraMacchina) { @@ -342,6 +430,26 @@ namespace MP.Data.Services.IOC return s?.Length > 17 ? s[..17] : s?.PadRight(17, '0') ?? string.Empty; } + /// + /// Recupero info ODL corrente da dati prod macchina + /// + /// + /// + private async Task GetCurrOdlByProdAsync(string idxMacchina) + { + string answ = ""; + // recupero stato... + var datiProd = await StatoProdMacchinaAsync(idxMacchina, DateTime.Now); + if (datiProd != null) + { + answ = datiProd.IdxOdl.ToString(); + } + // ultimo controllo su idxOdl... + answ = answ == "" ? "0" : answ; + // restituisco! + return answ; + } + /// /// Implementa gestione recupero cache da memoria o da obj esterno + cache memoria /// @@ -897,6 +1005,40 @@ namespace MP.Data.Services.IOC return answ; } + /// + /// Stato prod macchina (completo) + /// + /// + /// + /// + private async Task StatoProdMacchinaAsync(string idxMacchina, DateTime dtReq, bool forceDb = false) + { + string cacheKey = $"IOC_StatoProd_{idxMacchina}"; + return await GetOrFetchAsync(cacheKey, async () => + { + StatoProdModel? result = new StatoProdModel(); + // cerco in _redisConn... + string currKey = $"{MP.Data.Utils.redisStatoProd}:{idxMacchina}:{dtReq:HHmm}"; + RedisValue rawData = await _redisDb.StringGetAsync(currKey); + if (rawData.HasValue && !forceDb) + { + result = JsonConvert.DeserializeObject($"{rawData}"); + } + else + { + result = await _repo.StatoProdMacchinaAsync(idxMacchina, dtReq); + // serializzo e salvo... + rawData = JsonConvert.SerializeObject(result); + await _redisDb.StringSetAsync(currKey, rawData, TimeSpan.FromSeconds(30)); + } + if (result == null) + { + result = new StatoProdModel(); + } + return result; + }, TimeSpan.FromSeconds(10)); + } + /// /// Restituisce valOut della stringa (SE disponibile) /// @@ -923,7 +1065,7 @@ namespace MP.Data.Services.IOC /// /// /// - private bool ValidateinputParams(string idxMacchina, string valore, string dtEve, string dtCurr) + private bool ValidateInputParams(string idxMacchina, string valore, string dtEve, string dtCurr) { bool isValid = false; // preparo stringa valori correnti diff --git a/MP.IOC/Controllers/IOBController.cs b/MP.IOC/Controllers/IOBController.cs index b30d13ce..4a486ff9 100644 --- a/MP.IOC/Controllers/IOBController.cs +++ b/MP.IOC/Controllers/IOBController.cs @@ -429,7 +429,8 @@ namespace MP.IOC.Controllers id = id.Replace("|", "#"); try { - var pzCount = await DService.pzCounterTcAsync(id); + var pzCount = await IOCService.PzCounterTcAsync(id); + //var pzCount = await DService.PzCounterTcAsync(id); return Ok(pzCount); } catch (Exception exc) @@ -478,7 +479,8 @@ namespace MP.IOC.Controllers id = id.Replace("|", "#"); try { - var odl = await DService.GetCurrOdlAsync(id); + var odl = await IOCService.GetCurrOdlAsync(id); + //var odl = await DService.GetCurrOdlAsync(id); return Ok($"{odl}"); } catch (Exception exc) @@ -815,7 +817,8 @@ namespace MP.IOC.Controllers try { await DService.ScriviKeepAliveAsync(id, DateTime.UtcNow); - var valori = await DService.GetTask2ExeMacchinaAsync(id); + var valori = await IOCService.GetTask2ExeMacchinaAsync(id); + //var valori = await DService.GetTask2ExeMacchinaAsync(id); if (valori == null || valori.Count == 0) return Ok(new Dictionary()); @@ -1206,8 +1209,7 @@ namespace MP.IOC.Controllers /// /// SALVA Counter x macchina restituendo il valore appena inviato o, se mancasse chiave - /// redis, del valore da DB - /// + /// redis, valore da DB /// /// GET: IOB/setCounter/5?counter=10 /// /// cod macchina @@ -1226,7 +1228,8 @@ namespace MP.IOC.Controllers Log.Debug($"Salvataggio counter | id: {id} | pzCount: {counter}"); try { - answ = await DService.saveCounterAsync(id, counter); + answ = await IOCService.SaveCounterAsync(id, counter); + //answ = await DService.SaveCounterAsync(id, counter); } catch (Exception exc) { diff --git a/MP.IOC/Data/MpDataService.cs b/MP.IOC/Data/MpDataService.cs index 6dc5d273..abce85b4 100644 --- a/MP.IOC/Data/MpDataService.cs +++ b/MP.IOC/Data/MpDataService.cs @@ -3147,7 +3147,7 @@ namespace MP.IOC.Data } else { - answ = await pzCounterTcAsync(idxMacchina); + answ = await PzCounterTcAsync(idxMacchina); // salvo in _redisConn... await redisDb.StringSetAsync(currKey, answ.ToString(), TimeSpan.FromSeconds(1)); } @@ -3164,7 +3164,7 @@ namespace MP.IOC.Data /// /// /// - public async Task pzCounterTcAsync(string idxMacchina) + public async Task PzCounterTcAsync(string idxMacchina) { int answ = -1; DateTime dataRif = DateTime.Now; @@ -3741,7 +3741,7 @@ namespace MP.IOC.Data /// /// contapezzi /// - public async Task saveCounterAsync(string idxMacchina, string counter) + public async Task SaveCounterAsync(string idxMacchina, string counter) { string answ = "0"; // inizio processing vero e proprio INPUT... @@ -3776,7 +3776,7 @@ namespace MP.IOC.Data } else { - int currCount = await pzCounterTcAsync(idxMacchina); + int currCount = await PzCounterTcAsync(idxMacchina); answ = currCount.ToString(); // salvo per meno tempo... await redisDb.StringSetAsync(currKey, answ); diff --git a/MP.IOC/MP.IOC.csproj b/MP.IOC/MP.IOC.csproj index f2baf173..216a00d5 100644 --- a/MP.IOC/MP.IOC.csproj +++ b/MP.IOC/MP.IOC.csproj @@ -4,7 +4,7 @@ net8.0 enable enable - 8.16.2605.609 + 8.16.2605.610 diff --git a/MP.IOC/Resources/ChangeLog.html b/MP.IOC/Resources/ChangeLog.html index 8e8d8134..e707de72 100644 --- a/MP.IOC/Resources/ChangeLog.html +++ b/MP.IOC/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MP-IOC -

      Versione: 8.16.2605.609

      +

      Versione: 8.16.2605.610


      Note di rilascio:
      • diff --git a/MP.IOC/Resources/VersNum.txt b/MP.IOC/Resources/VersNum.txt index 0a727783..311dfe39 100644 --- a/MP.IOC/Resources/VersNum.txt +++ b/MP.IOC/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2605.609 +8.16.2605.610 diff --git a/MP.IOC/Resources/manifest.xml b/MP.IOC/Resources/manifest.xml index 0498bfc7..3dbadca7 100644 --- a/MP.IOC/Resources/manifest.xml +++ b/MP.IOC/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2605.609 + 8.16.2605.610 https://nexus.steamware.net/repository/SWS/MP-IOC/stable/LAST/MP.IOC.zip https://nexus.steamware.net/repository/SWS/MP-IOC/stable/LAST/ChangeLog.html false