From 36890d34c1dede5f08a07eabe8f8f832b5738631 Mon Sep 17 00:00:00 2001 From: Samuele Locatelli Date: Mon, 27 Apr 2026 14:56:48 +0200 Subject: [PATCH] Update saveDataItem: reinserito metodo mongoDB --- MP.Core/DTO/MtcSetupDto.cs | 14 ++++ MP.Data/Controllers/MpMongoController.cs | 46 +++++++++--- MP.Data/Services/ListSelectDataSrv.cs | 80 +++++++++++++++++++-- MP.IOC/Controllers/IOBController.cs | 5 +- MP.IOC/Data/MpDataService.cs | 91 ++++++------------------ MP.IOC/MP.IOC.csproj | 2 +- MP.IOC/Resources/ChangeLog.html | 2 +- MP.IOC/Resources/VersNum.txt | 2 +- MP.IOC/Resources/manifest.xml | 2 +- MP.SPEC/MP.SPEC.csproj | 2 +- MP.SPEC/Resources/ChangeLog.html | 2 +- MP.SPEC/Resources/VersNum.txt | 2 +- MP.SPEC/Resources/manifest.xml | 2 +- 13 files changed, 158 insertions(+), 94 deletions(-) create mode 100644 MP.Core/DTO/MtcSetupDto.cs diff --git a/MP.Core/DTO/MtcSetupDto.cs b/MP.Core/DTO/MtcSetupDto.cs new file mode 100644 index 00000000..250fae2f --- /dev/null +++ b/MP.Core/DTO/MtcSetupDto.cs @@ -0,0 +1,14 @@ +using MP.Core.Objects; + +namespace MP.Core.DTO +{ + public class MtcSetupDto + { + #region Public Properties + + public List DataItems { get; set; } = new(); + public string IdxMacchina { get; set; } = ""; + + #endregion Public Properties + } +} \ No newline at end of file diff --git a/MP.Data/Controllers/MpMongoController.cs b/MP.Data/Controllers/MpMongoController.cs index cebf9a13..233f1689 100644 --- a/MP.Data/Controllers/MpMongoController.cs +++ b/MP.Data/Controllers/MpMongoController.cs @@ -1,18 +1,16 @@ using Microsoft.Extensions.Configuration; +using MongoDB.Driver; +using MP.Core.Conf; +using MP.Core.DTO; +using MP.Core.Objects; +using MP.Data.MgModels; +using Newtonsoft.Json; using NLog; -using NLog.Fluent; using System; using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using MongoDB.Driver; -using MongoDB.Bson; -using MP.Data.MgModels; using System.IO; -using MP.Core.Conf; -using Newtonsoft.Json; -using static MP.Data.MgModels.RecipeModel; +using System.Linq; +using System.Threading.Tasks; namespace MP.Data.Controllers { @@ -112,6 +110,34 @@ namespace MP.Data.Controllers return answ; } + /// + /// Salva i dataItems della macchina indicata in MongoDB + /// + /// + /// + /// + public bool SaveMachineDataItems(string idxMacchina, List dataItems) + { + bool answ = false; + var collMtcSetup = mongoDb.GetCollection("MtcSetup"); + // compongo filtro ricerca e metodo update + var filter = Builders.Filter.Eq(u => u.IdxMacchina, idxMacchina); + // chiamo update: cerco riga, se c'è aggiorno sennò creo + MtcSetupDto newDoc = new MtcSetupDto() + { + IdxMacchina = idxMacchina, + DataItems = dataItems + }; + // elimino se ci fosse già... + collMtcSetup.DeleteMany(filter); + // inserisco ex novo! + collMtcSetup.InsertOne(newDoc); + answ = true; + return answ; + } + + + /// /// Init ricetta dato PODL + conf /// diff --git a/MP.Data/Services/ListSelectDataSrv.cs b/MP.Data/Services/ListSelectDataSrv.cs index 97c6d3c0..b541ee06 100644 --- a/MP.Data/Services/ListSelectDataSrv.cs +++ b/MP.Data/Services/ListSelectDataSrv.cs @@ -3,6 +3,7 @@ using MP.Data.DbModels; using Newtonsoft.Json; using NLog; using StackExchange.Redis; +using System; using System.Collections.Generic; using System.Data; using System.Diagnostics; @@ -283,12 +284,82 @@ namespace MP.Data.Services #region Private Methods /// - /// Esegue flush memoria _redisConn dato pat2Flush + /// Esegue flush memoria _redisConn dato pattern /// - /// + /// /// - private async Task ExecFlushRedisPattern(RedisValue pat2Flush) + private async Task ExecFlushRedisPattern(RedisValue pattern) { + Log.Debug($"Richiesta flush pattern: {pattern}"); + + // 1. Target ONLY master (le replica sono in read-only) + var master = _redisConn.GetEndPoints() + .Where(ep => _redisConn.GetServer(ep).IsConnected && !_redisConn.GetServer(ep).IsReplica) + .FirstOrDefault(); + + if (master == null) + { + Log.Warn($"Nessun master Redis raggiungibile per il pattern {pattern}"); + return false; + } + + // 2. Flush intero DB se richiesto + if (pattern.ToString() == "*") + { + Log.Debug($"Full DB reset da pattern {pattern}"); + if (master != null) + { + _redisConn.GetServer(master).FlushDatabase(_redisDb.Database); + Log.Info($"Flush database {_redisDb.Database} completato"); + } + return true; + } + // altrimenti faccio ciclo! + var server = _redisConn.GetServer(master); + var db = _redisConn.GetDatabase(_redisDb.Database); + const int batchSize = 500; + var batch = new List(batchSize); + int deletedCount = 0; + + try + { + // KeysAsync usa SCAN automaticamente quando i risultati sono grandi + await foreach (var key in server.KeysAsync( + database: _redisDb.Database, + pattern: pattern.ToString(), + pageSize: batchSize)) + { + batch.Add(key); + if (batch.Count >= batchSize) + { + // Esecuzione batch in parallelo controllato + await Task.WhenAll(batch.Select(k => db.KeyDeleteAsync(k))); + batch.Clear(); + deletedCount += batchSize; + } + } + + // Restanti + if (batch.Count > 0) + { + await Task.WhenAll(batch.Select(k => db.KeyDeleteAsync(k))); + deletedCount += batch.Count; + } + + Log.Info("Flush pattern {Pattern}: eliminate {Count} chiavi", pattern, deletedCount); + return true; + } + catch (RedisConnectionException ex) + { + Log.Error(ex, "Connessione Redis persa durante il flush di {pattern}", pattern); + return false; + } + catch (Exception ex) + { + Log.Error(ex, "Errore imprevisto nel flush pattern {pattern}", pattern); + throw; + } +#if false bool answ = false; var masterEndpoint = _redisConn.GetEndPoints() .Where(ep => _redisConn.GetServer(ep).IsConnected && !_redisConn.GetServer(ep).IsReplica) @@ -320,7 +391,8 @@ namespace MP.Data.Services } answ = true; } - return answ; + return answ; +#endif } #endregion Private Methods diff --git a/MP.IOC/Controllers/IOBController.cs b/MP.IOC/Controllers/IOBController.cs index 98b12049..2aed29e0 100644 --- a/MP.IOC/Controllers/IOBController.cs +++ b/MP.IOC/Controllers/IOBController.cs @@ -1153,8 +1153,9 @@ namespace MP.IOC.Controllers string answ = "NO"; try { - // recupero IP del client remoto - var agent = Request.Headers["User-Agent"].ToString(); + // recupero IP del client remoto, se vuoto IOC + string agent = Request.Headers["User-Agent"].ToString() ?? "IOC"; + agent = string.IsNullOrWhiteSpace(agent) ? "IOC" : agent; //var ipv4 = HttpContext.Connection.RemoteIpAddress?.ToString(); var ipv4 = HttpContext.Connection.RemoteIpAddress?.MapToIPv4().ToString(); diff --git a/MP.IOC/Data/MpDataService.cs b/MP.IOC/Data/MpDataService.cs index 37bd5c65..11f047f2 100644 --- a/MP.IOC/Data/MpDataService.cs +++ b/MP.IOC/Data/MpDataService.cs @@ -3350,27 +3350,6 @@ namespace MP.IOC.Data /// /// /// -#if false - public async Task RedisFlushPatternAsync(RedisValue pattern) - { - bool answ = false; - var listEndpoints = redisConnAdmin.GetEndPoints(); - foreach (var endPoint in listEndpoints) - { - var server = redisConnAdmin.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; - } -#endif public async Task RedisFlushPatternAsync(RedisValue pattern) { Log.Debug($"Richiesta flush pattern: {pattern}"); @@ -3536,28 +3515,16 @@ namespace MP.IOC.Data /// public async Task RemRebootLogAddAsync(RemoteRebootLogModel newRec) { - bool fatto = false; -#if false - // insert del record - fatto = await IocDbController.RemRebootLogAddAsync(newRec); - // pulizia record vecchi - int num2keep = 5; - string confVal = await tryGetConfig("IO_NumReboot2Keep"); - if (!string.IsNullOrEmpty(confVal)) - { - int.TryParse(confVal, out num2keep); - } - fatto = await IocDbController.RemRebootLogKeepLastAsync(num2keep); -#endif - // insert del record + pulizia - string confVal = await tryGetConfig("IO_NumReboot2Keep"); int num2keep = int.TryParse(confVal, out int n) ? n : 5; - fatto = await IocDbController.RemRebootLogAddAndCleanAsync(newRec, num2keep); - - // svuota cache - var currKey = $"{Utils.redisRemRebLog}:*"; - await RedisFlushPatternAsync(currKey); + // insert del record + pulizia + bool fatto = await IocDbController.RemRebootLogAddAndCleanAsync(newRec, num2keep); + if (fatto) + { + // svuota cache + var currKey = $"{Utils.redisRemRebLog}:*"; + await RedisFlushPatternAsync(currKey); + } return fatto; } @@ -3865,16 +3832,23 @@ namespace MP.IOC.Data public async Task SaveDataItemsAsync(string id, List dataList) { bool answ = false; - - if (useFactory) + if (mongoController != null) { - await using var scope = _scopeFactory.CreateAsyncScope(); - var mtcService = scope.ServiceProvider.GetRequiredService(); - answ = await mtcService.ReplaceMachineDataAsync(id, dataList); + answ = mongoController.SaveMachineDataItems(id, dataList); } else { - answ = await MtcService.ReplaceMachineDataAsync(id, dataList); + // modalità con SqlSb (no mongo) + if (useFactory) + { + await using var scope = _scopeFactory.CreateAsyncScope(); + var mtcService = scope.ServiceProvider.GetRequiredService(); + answ = await mtcService.ReplaceMachineDataAsync(id, dataList); + } + else + { + answ = await MtcService.ReplaceMachineDataAsync(id, dataList); + } } return answ; @@ -4944,28 +4918,5 @@ namespace MP.IOC.Data #endregion Private Methods -#if false - public bool RedisSetKey(string valKey, string redVal) - { - bool answ = redisDb.StringSet(Utils.RedKeyHash(valKey), redVal); - return answ; - } - public async Task RedisSetKeyAsync(string valKey, string redVal) - { - bool answ = await redisDb.StringSetAsync(Utils.RedKeyHash(valKey), redVal); - return answ; - } - - public bool RedisSetKey(RedisKey valKey, string redVal, int TTL_sec) - { - bool answ = redisDb.StringSet(Utils.RedKeyHash(valKey), redVal, TimeSpan.FromSeconds(TTL_sec)); - return answ; - } - public async Task RedisSetKeyAsync(RedisKey valKey, string redVal, int TTL_sec) - { - bool answ = await redisDb.StringSetAsync(Utils.RedKeyHash(valKey), redVal, TimeSpan.FromSeconds(TTL_sec)); - return answ; - } -#endif } } \ No newline at end of file diff --git a/MP.IOC/MP.IOC.csproj b/MP.IOC/MP.IOC.csproj index d8a4a194..dcf863ec 100644 --- a/MP.IOC/MP.IOC.csproj +++ b/MP.IOC/MP.IOC.csproj @@ -4,7 +4,7 @@ net8.0 enable enable - 6.16.2604.2711 + 6.16.2604.2714 diff --git a/MP.IOC/Resources/ChangeLog.html b/MP.IOC/Resources/ChangeLog.html index 6bfd4545..e374d315 100644 --- a/MP.IOC/Resources/ChangeLog.html +++ b/MP.IOC/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MP-IOC -

Versione: 6.16.2604.2711

+

Versione: 6.16.2604.2714


Note di rilascio:
  • diff --git a/MP.IOC/Resources/VersNum.txt b/MP.IOC/Resources/VersNum.txt index d86bbbf2..376ba778 100644 --- a/MP.IOC/Resources/VersNum.txt +++ b/MP.IOC/Resources/VersNum.txt @@ -1 +1 @@ -6.16.2604.2711 +6.16.2604.2714 diff --git a/MP.IOC/Resources/manifest.xml b/MP.IOC/Resources/manifest.xml index b0400a23..e0934824 100644 --- a/MP.IOC/Resources/manifest.xml +++ b/MP.IOC/Resources/manifest.xml @@ -1,6 +1,6 @@ - 6.16.2604.2711 + 6.16.2604.2714 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 diff --git a/MP.SPEC/MP.SPEC.csproj b/MP.SPEC/MP.SPEC.csproj index d1845ee3..270b6b9c 100644 --- a/MP.SPEC/MP.SPEC.csproj +++ b/MP.SPEC/MP.SPEC.csproj @@ -5,7 +5,7 @@ enable enable MP.SPEC - 6.16.2604.712 + 6.16.2604.2711 1800a78a-6ff1-40f9-b490-87fb8bfc1394 en diff --git a/MP.SPEC/Resources/ChangeLog.html b/MP.SPEC/Resources/ChangeLog.html index 02e4d76c..18a6d874 100644 --- a/MP.SPEC/Resources/ChangeLog.html +++ b/MP.SPEC/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MAPOSPEC -

    Versione: 6.16.2604.712

    +

    Versione: 6.16.2604.2711


    Note di rilascio:
    • diff --git a/MP.SPEC/Resources/VersNum.txt b/MP.SPEC/Resources/VersNum.txt index e400f432..d86bbbf2 100644 --- a/MP.SPEC/Resources/VersNum.txt +++ b/MP.SPEC/Resources/VersNum.txt @@ -1 +1 @@ -6.16.2604.712 +6.16.2604.2711 diff --git a/MP.SPEC/Resources/manifest.xml b/MP.SPEC/Resources/manifest.xml index 3207aa51..188ddce1 100644 --- a/MP.SPEC/Resources/manifest.xml +++ b/MP.SPEC/Resources/manifest.xml @@ -1,6 +1,6 @@ - 6.16.2604.712 + 6.16.2604.2711 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