diff --git a/MP.Data/Controllers/MpSpecController.cs b/MP.Data/Controllers/MpSpecController.cs
index cb420ac9..47117287 100644
--- a/MP.Data/Controllers/MpSpecController.cs
+++ b/MP.Data/Controllers/MpSpecController.cs
@@ -4,15 +4,12 @@ using Microsoft.Extensions.Configuration;
using MP.Data.DatabaseModels;
using MP.Data.DTO;
using NLog;
-using NLog.LayoutRenderers;
using System;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
using System.Linq;
-using System.Runtime.InteropServices;
using System.Threading.Tasks;
-using ZXing;
using static EgwCoreLib.Utils.DtUtils;
namespace MP.Data.Controllers
@@ -551,32 +548,35 @@ namespace MP.Data.Controllers
///
///
///
- ///
- public async Task FluxLogDataRedux(string idxMaccSel, List fluxList, Periodo currPeriodo, Enum.ValSelection valMode, Enum.DataInterval intReq)
+ ///
+ /// Restitusice list dei record statistiche raccolti (da integrare a quelli rpesenti in Redis...)
+ ///
+ public async Task> FluxLogDataRedux(string idxMaccSel, List fluxList, Periodo currPeriodo, Enum.ValSelection valMode, Enum.DataInterval intReq, int maxItem)
{
+ List procStats = new List();
Log.Info($"Inizio FluxLogDataRedux | idxMaccSel: {idxMaccSel} | periodo: {currPeriodo.Inizio} --> {currPeriodo.Fine}");
- bool fatto = false;
TimeSpan step = TimeSpan.FromHours(1);
switch (intReq)
{
case Enum.DataInterval.minute:
- step = TimeSpan.FromMinutes(1);
+ step = TimeSpan.FromMinutes(1.00 / maxItem);
break;
+
case Enum.DataInterval.hour:
- step = TimeSpan.FromHours(1);
+ step = TimeSpan.FromHours(1.00 / maxItem);
break;
+
case Enum.DataInterval.day:
- step = TimeSpan.FromDays(1);
+ step = TimeSpan.FromDays(1.00 / maxItem);
break;
+
default:
break;
}
- List procStats = new List();
// setup parametri costanti x stored
var pIdxMacchina = new SqlParameter("@IdxMacchina", idxMaccSel);
var pOnlyTest = new SqlParameter("@OnlyTest", false);
- var pDoReIndex = new SqlParameter("@DoReIndex", false); // sarà cambiato solo alla fine x avere un reindex finale x macchina
// processo 1:1 ogni flusso
foreach (var item in fluxList)
@@ -591,10 +591,11 @@ namespace MP.Data.Controllers
DateTime dtCursStart = currPeriodo.Inizio;
DateTime dtCursEnd = dtCursStart.Add(step);
bool setCompleted = false;
- // dbCOntext x ogni singolo flusso
+ // dbContext x ogni singolo flusso
using (var dbCtx = new MoonProContext(_configuration))
{
- // li processo per intervallo richiesto, cercando dati nel periodo e selezionando VC
+ // li processo per intervallo richiesto, cercando dati nel periodo e
+ // selezionando VC
while (!setCompleted)
{
// ora recupero TUTTI i dati della macchina
@@ -605,7 +606,7 @@ namespace MP.Data.Controllers
int numRec = currFlux.Count;
numRecProc += numRec;
- if (numRec > 1)
+ if (numRec > maxItem)
{
if (dtCursStart > currPeriodo.Fine)
{
@@ -613,7 +614,6 @@ namespace MP.Data.Controllers
}
List listPeriodi = new List();
-
switch (valMode)
{
case Enum.ValSelection.First:
@@ -622,18 +622,33 @@ namespace MP.Data.Controllers
// salvo periodo!
listPeriodi.Add(new Periodo(recStart.dtEvento, dtCursEnd));
break;
+
case Enum.ValSelection.Last:
// recupero ultimo item
var recEnd = currFlux.LastOrDefault();
// salvo periodo!
listPeriodi.Add(new Periodo(dtCursStart, recEnd.dtEvento));
break;
+
case Enum.ValSelection.Center:
- var recCent = currFlux.Skip(numRec / 2).FirstOrDefault();
- // salvo 2 periodi!
+ int idx = 1;
+ // per iniziare mi metto a 1/(n+1) rec come step
+ var recCent = currFlux.Skip(idx / (maxItem + 1)).FirstOrDefault();
listPeriodi.Add(new Periodo(dtCursStart, recCent.dtEvento));
+ // salvo restanti periodi (se > 1)!
+ if (maxItem > 1)
+ {
+ for (int i = 2; i < maxItem; i++)
+ {
+ DateTime dtInizio = recCent.dtEvento;
+ recCent = currFlux.Skip(i / (maxItem + 1)).FirstOrDefault();
+ listPeriodi.Add(new Periodo(dtInizio, recCent.dtEvento));
+ }
+ }
+ // aggiungo ultimo...
listPeriodi.Add(new Periodo(recCent.dtEvento.AddSeconds(1), dtCursEnd));
break;
+
default:
break;
}
@@ -646,7 +661,7 @@ namespace MP.Data.Controllers
var pDtEnd = new SqlParameter("@DtEnd", slot.Fine);
var dbResult = dbCtx
.Database
- .ExecuteSqlRaw("EXEC man.stp_ReduceFluxLog @IdxMacchina, @CodFlux, @DtStart, @DtEnd, @OnlyTest, @DoReIndex", pIdxMacchina, pCodFlux, pDtStart, pDtEnd, pOnlyTest, pDoReIndex);
+ .ExecuteSqlRaw("EXEC man.stp_ReduceFluxLog @IdxMacchina, @CodFlux, @DtStart, @DtEnd, @OnlyTest", pIdxMacchina, pCodFlux, pDtStart, pDtEnd, pOnlyTest);
}
}
@@ -657,44 +672,19 @@ namespace MP.Data.Controllers
}
// fermo cronometro e salvo su DB...
sw.Stop();
- LogFLDedupModel currStat = new LogFLDedupModel()
+ StatDedupDTO currStat = new StatDedupDTO()
{
IdxMacchina = idxMaccSel,
CodFlux = item,
- DtRif = DateTime.Now,
+ Interval = intReq,
+ Num4Int = maxItem,
NumRec = numRecProc,
ProcTime = sw.Elapsed.TotalSeconds
};
procStats.Add(currStat);
}
-
- // salvo le statistiche di processing...
- fatto = LogFLDedupInsert(procStats);
Log.Info($"FINE FluxLogDataRedux | idxMaccSel: {idxMaccSel} | periodo: {currPeriodo.Inizio} --> {currPeriodo.Fine}");
- return fatto;
- }
- ///
- /// Inserimento record risultati deduplica FluxLog
- ///
- ///
- ///
- protected bool LogFLDedupInsert(List rec2ins)
- {
- bool fatto = false;
- using (var dbCtx = new MoonProContext(_configuration))
- {
- try
- {
- dbCtx.DbSetLogFLDedup.AddRange(rec2ins);
- var res = dbCtx.SaveChanges();
- fatto = res != 0;
- }
- catch (Exception exc)
- {
- Log.Error($"Errore in fase inserimento log dedup x FL{Environment.NewLine}{exc}");
- }
- }
- return fatto;
+ return procStats;
}
///
@@ -722,6 +712,39 @@ namespace MP.Data.Controllers
return dbResult;
}
+ ///
+ /// Stored manutenzione del DB
+ ///
+ /// Esegue realmente il task
+ /// Aggiornamento statistiche
+ /// Salvataggio
+ /// def: 1000
+ /// def: 10
+ /// def: 50
+ ///
+ public async Task ForceDbMaint(bool doExec, bool doUpdStat, bool doSave, int minPgCnt, int minAvgFrag, int maxAvgFragReb)
+ {
+ Log.Info($"Inizio ForceDbMaint");
+ bool fatto = false;
+ using (var dbCtx = new MoonProContext(_configuration))
+ {
+ var pFlgExec = new SqlParameter("@FlgExec", doExec ? "Y" : "N");
+ var pFlgUpdStat = new SqlParameter("@FlgUpdStat", doUpdStat ? "Y" : "N");
+ var pFlgSave = new SqlParameter("@FlgSave", doSave ? "Y" : "N");
+ var pMinPgCnt = new SqlParameter("@min_page_count", minPgCnt);
+ var pMinAvgFrag = new SqlParameter("@min_avg_fragmentation_in_percent", minAvgFrag);
+ var pMaxAvgFrag = new SqlParameter("@max_avg_fragmentation_per_rebuild", maxAvgFragReb);
+
+ var dbResult = await dbCtx
+ .Database
+ .ExecuteSqlRawAsync("EXEC man.stp_Utility_Maintanance");
+ //.ExecuteSqlRaw("EXEC man.stp_Utility_Maintanance @FlgExec, @FlgUpdStat, @FlgSave, @min_page_count, @min_avg_fragmentation_in_percent, @max_avg_fragmentation_per_rebuild", pFlgExec, pFlgUpdStat, pFlgSave, pMinPgCnt, pMinAvgFrag, pMaxAvgFrag);
+ fatto = true;
+ }
+ Log.Info($"FINE ForceDbMaint");
+ return fatto;
+ }
+
///
/// Elenco giacenze
///
diff --git a/MP.Data/DTO/StatDedupDTO.cs b/MP.Data/DTO/StatDedupDTO.cs
new file mode 100644
index 00000000..076aca72
--- /dev/null
+++ b/MP.Data/DTO/StatDedupDTO.cs
@@ -0,0 +1,56 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.DataAnnotations.Schema;
+using System.ComponentModel.DataAnnotations;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+
+//
+// This is here so CodeMaid doesn't reorganize this document
+//
+namespace MP.Data.DTO
+{
+ public class StatDedupDTO
+ {
+ ///
+ /// Macchina
+ ///
+ public string IdxMacchina { get; set; } = "";
+
+ ///
+ /// Cod Flusso interessato
+ ///
+ public string CodFlux { get; set; } = "";
+
+ ///
+ /// Tipo di intervallo richiesto
+ ///
+ public Enum.DataInterval Interval { get; set; } = Enum.DataInterval.hour;
+
+ ///
+ /// num max di item per intervallo
+ ///
+ public int Num4Int { get; set; } = 1;
+
+ ///
+ /// Num record processati (iniziali)
+ ///
+ public int NumRec { get; set; } = 1;
+
+ ///
+ /// Tempo processing (secondi)
+ ///
+ public double ProcTime { get; set; } = 1;
+
+ ///
+ /// Tempo processing atteso in ms per record
+ ///
+ [NotMapped]
+ public double ProcTimeMs
+ {
+ get => (ProcTime * 1000) / (NumRec > 1 ? NumRec : 1);
+ }
+ }
+}
diff --git a/MP.Data/DatabaseModels/LogFLDedupModel.cs b/MP.Data/DatabaseModels/LogFLDedupModel.cs
deleted file mode 100644
index 4e3ffee1..00000000
--- a/MP.Data/DatabaseModels/LogFLDedupModel.cs
+++ /dev/null
@@ -1,40 +0,0 @@
-using System;
-using System.ComponentModel.DataAnnotations;
-using System.ComponentModel.DataAnnotations.Schema;
-
-
-#nullable disable
-//
-// This is here so CodeMaid doesn't reorganize this document
-//
-namespace MP.Data.DatabaseModels
-{
- [Table("LogFLDedup")]
- public partial class LogFLDedupModel
- {
- #region Public Properties
-
- [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
- public int DedupIdx { get; set; } = 0;
-
- [MaxLength(50)]
- public string IdxMacchina { get; set; } = "";
-
- [MaxLength(50)]
- public string CodFlux { get; set; } = "";
-
- public DateTime DtRif { get; set; }=DateTime.Now;
-
- ///
- /// Num record processati
- ///
- public int NumRec { get; set; } = 0;
-
- ///
- /// Tempo processing (secondi)
- ///
- public double ProcTime { get; set; } = 1;
-
- #endregion Public Properties
- }
-}
\ No newline at end of file
diff --git a/MP.Data/Enum.cs b/MP.Data/Enum.cs
index 3e1c6a41..3a5afa29 100644
--- a/MP.Data/Enum.cs
+++ b/MP.Data/Enum.cs
@@ -18,13 +18,13 @@ namespace MP.Data
///
First,
///
- /// Selezione ULTIMO valore del set
- ///
- Last,
- ///
/// Selezione Moda (norma) = elemento centrale
///
- Center
+ Center,
+ ///
+ /// Selezione ULTIMO valore del set
+ ///
+ Last
}
///
/// Intervallo dati (es per definizione quanti dati FluxLog tenere x intervallo
diff --git a/MP.Data/MoonProContext.cs b/MP.Data/MoonProContext.cs
index 54fd7757..43503dc5 100644
--- a/MP.Data/MoonProContext.cs
+++ b/MP.Data/MoonProContext.cs
@@ -89,10 +89,7 @@ namespace MP.Data
public virtual DbSet DbSetStTemplateRows { get; set; }
public virtual DbSet DbSetCommenti { get; set; }
- public virtual DbSet DbSetFNQ { get; set; }
- public virtual DbSet DbSetLogFLDedup { get; set; }
-
-
+ public virtual DbSet DbSetFNQ { get; set; }
public virtual DbSet DbSetVSEB { get; set; }
public virtual DbSet DbSetVSODL { get; set; }
diff --git a/MP.Data/Utils.cs b/MP.Data/Utils.cs
index 4a4efbaf..5b89a344 100644
--- a/MP.Data/Utils.cs
+++ b/MP.Data/Utils.cs
@@ -232,6 +232,7 @@ namespace MP.Data
public const string redisConfKey = redisBaseAddr + "Cache:Config";
public const string redisAKVKey = redisBaseAddr + "Cache:AKV";
public const string redisParetoFLKey = redisBaseAddr + "Cache:ParetoFL";
+ public const string redisStatsProcFL = redisBaseAddr + "Stats:ProcessFL";
public const string redisDossByMac = redisBaseAddr + "Cache:DossByMac";
public const string redisFluxByMac = redisBaseAddr + "Cache:FluxByMac";
public const string redisFluxLogFilt = redisBaseAddr + "Cache:FluxLogFilt";
diff --git a/MP.SPEC/Components/FLStatusList.razor.cs b/MP.SPEC/Components/FLStatusList.razor.cs
index cf06f3a1..f25e8b8c 100644
--- a/MP.SPEC/Components/FLStatusList.razor.cs
+++ b/MP.SPEC/Components/FLStatusList.razor.cs
@@ -18,6 +18,8 @@ namespace MP.SPEC.Components
[Parameter]
public EventCallback E_TotalCount { get; set; }
+ [Parameter]
+ public EventCallback E_TotalRec { get; set; }
[Parameter]
public string IdxMaccSel { get; set; } = "";
@@ -80,6 +82,18 @@ namespace MP.SPEC.Components
}
}
}
+ protected int TotalRecords
+ {
+ get => totRecords;
+ set
+ {
+ if (totRecords != value)
+ {
+ totRecords = value;
+ E_TotalRec.InvokeAsync(value).ConfigureAwait(false);
+ }
+ }
+ }
#endregion Protected Properties
@@ -104,6 +118,7 @@ namespace MP.SPEC.Components
lastPeriodo = CurrPeriodo;
ListComplete = await MDataServ.ParetoFluxLog(IdxMaccSel, CurrPeriodo.Inizio, CurrPeriodo.Fine);
TotalCount = ListComplete.Count;
+ TotalRecords = ListComplete.Sum(x => x.Qty);
FluxList = ListComplete.Select(x => x.CodFlux).ToList();
}
// esegue paginazione
@@ -133,6 +148,7 @@ namespace MP.SPEC.Components
private string idxMaccLast = "";
private bool isProcessing = false;
private int totalCount = 0;
+ private int totRecords = 0;
#endregion Private Fields
diff --git a/MP.SPEC/Data/MpDataService.cs b/MP.SPEC/Data/MpDataService.cs
index 64ceb227..17cf0722 100644
--- a/MP.SPEC/Data/MpDataService.cs
+++ b/MP.SPEC/Data/MpDataService.cs
@@ -691,6 +691,24 @@ namespace MP.SPEC.Data
return answ;
}
+ ///
+ /// Funzione di Data Reduction x FluxLog
+ ///
+ /// Macchina
+ /// Elenco FL da processare
+ /// Periodo
+ /// modalità sel valore
+ /// intervallo di analisi
+ /// max num per intervallo
+ ///
+ public async Task FluxLogDataRedux(string idxMaccSel, List fluxList, DtUtils.Periodo currPeriodo, ValSelection valMode, DataInterval intReq, int maxItem)
+ {
+ List procStats = await dbController.FluxLogDataRedux(idxMaccSel, fluxList, currPeriodo, valMode, intReq, maxItem);
+ // effettuo merge statistiche...
+ ProcStatMerge(procStats);
+ await FlushCacheFluxLog();
+ }
+
public List FluxLogDtoGetByFlux(string Valore)
{
List answ = new List();
@@ -760,6 +778,22 @@ namespace MP.SPEC.Data
return result;
}
+ ///
+ /// Stored manutenzione del DB
+ ///
+ /// Esegue realmente il task
+ /// Aggiornamento statistiche
+ /// Salvataggio
+ /// def: 1000
+ /// def: 10
+ /// def: 50
+ ///
+ public async Task ForceDbMaint(bool doExec = true, bool doUpdStat = true, bool doSave = true, int minPgCnt = 1000, int minAvgFrag = 10, int maxAvgFragReb = 50)
+ {
+ await dbController.ForceDbMaint(doExec, doUpdStat, doSave, minPgCnt, minAvgFrag, maxAvgFragReb);
+ await FlushCacheFluxLog();
+ }
+
///
/// Init ricetta
///
@@ -1416,6 +1450,27 @@ namespace MP.SPEC.Data
return dbResult;
}
+ ///
+ /// Restituisce le statistiche di processo correnti x depluplica FluxLog
+ ///
+ ///
+ public List ProcFLStats()
+ {
+ List actStats = new List();
+ string currKey = $"{Utils.redisStatsProcFL}";
+ // recupero i record statistiche correnti
+ RedisValue rawData = redisDb.StringGet(currKey);
+ if (rawData.HasValue)
+ {
+ var rawStats = JsonConvert.DeserializeObject>($"{rawData}");
+ if (rawStats != null)
+ {
+ actStats = rawStats;
+ }
+ }
+ return actStats;
+ }
+
///
/// Ricerca ricetta su MongoDB dato PODL
///
@@ -1711,6 +1766,45 @@ namespace MP.SPEC.Data
return TimeSpan.FromMinutes(rndValue);
}
+ protected bool ProcStatMerge(List procStats)
+ {
+ bool answ = false;
+ List actStats = ProcFLStats();
+ // se fosse vuoto --> add diretto
+ if (actStats.Count == 0)
+ {
+ actStats.AddRange(procStats);
+ }
+ else
+ {
+ // aggiorno su redis i record statistiche 1:1...
+ foreach (var recStat in procStats)
+ {
+ // cerco se ci fosse x aggiornare
+ var currRec = actStats.Where(x => x.IdxMacchina == recStat.IdxMacchina
+ && x.CodFlux == recStat.CodFlux
+ && x.Interval == recStat.Interval
+ && x.Num4Int == recStat.Num4Int).FirstOrDefault();
+ // se trovato aggiorno
+ if (currRec != null)
+ {
+ currRec.ProcTime += recStat.ProcTime;
+ currRec.NumRec += recStat.NumRec;
+ }
+ // altrimenti aggiungo
+ else
+ {
+ actStats.Add(recStat);
+ }
+ }
+ }
+ // salvo record statistiche
+ var rawData = JsonConvert.SerializeObject(actStats);
+ string currKey = $"{Utils.redisStatsProcFL}";
+ redisDb.StringSet(currKey, rawData);
+ return answ;
+ }
+
#endregion Protected Methods
#region Private Fields
@@ -1772,21 +1866,6 @@ namespace MP.SPEC.Data
await RedisFlushPatternAsync(pattern);
}
- ///
- /// Funzione di Data Reduction x FluxLog
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- public async Task FluxLogDataRedux(string idxMaccSel, List fluxList, DtUtils.Periodo currPeriodo, ValSelection valMode, DataInterval intReq)
- {
- await dbController.FluxLogDataRedux(idxMaccSel, fluxList, currPeriodo, valMode, intReq);
- await FlushCacheFluxLog();
- }
-
#endregion Private Methods
}
}
\ No newline at end of file
diff --git a/MP.SPEC/MP.SPEC.csproj b/MP.SPEC/MP.SPEC.csproj
index eefa302b..b90e07e9 100644
--- a/MP.SPEC/MP.SPEC.csproj
+++ b/MP.SPEC/MP.SPEC.csproj
@@ -5,7 +5,7 @@
enable
enable
MP.SPEC
- 6.16.2310.2112
+ 6.16.2310.2320
diff --git a/MP.SPEC/Pages/FluxLogStatus.razor b/MP.SPEC/Pages/FluxLogStatus.razor
index 372c0e5a..754ec856 100644
--- a/MP.SPEC/Pages/FluxLogStatus.razor
+++ b/MP.SPEC/Pages/FluxLogStatus.razor
@@ -3,8 +3,8 @@