Merge branch 'develop' of https://gitlab.steamware.net/steamware/mapo-core into develop
This commit is contained in:
@@ -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
|
||||
/// <param name="currPeriodo"></param>
|
||||
/// <param name="valMode"></param>
|
||||
/// <param name="intReq"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<bool> FluxLogDataRedux(string idxMaccSel, List<string> fluxList, Periodo currPeriodo, Enum.ValSelection valMode, Enum.DataInterval intReq)
|
||||
/// <returns>
|
||||
/// Restitusice list dei record statistiche raccolti (da integrare a quelli rpesenti in Redis...)
|
||||
/// </returns>
|
||||
public async Task<List<StatDedupDTO>> FluxLogDataRedux(string idxMaccSel, List<string> fluxList, Periodo currPeriodo, Enum.ValSelection valMode, Enum.DataInterval intReq, int maxItem)
|
||||
{
|
||||
List<StatDedupDTO> procStats = new List<StatDedupDTO>();
|
||||
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<LogFLDedupModel> procStats = new List<LogFLDedupModel>();
|
||||
|
||||
// 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<Periodo> listPeriodi = new List<Periodo>();
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
/// <summary>
|
||||
/// Inserimento record risultati deduplica FluxLog
|
||||
/// </summary>
|
||||
/// <param name="rec2ins"></param>
|
||||
/// <returns></returns>
|
||||
protected bool LogFLDedupInsert(List<LogFLDedupModel> 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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -722,6 +712,39 @@ namespace MP.Data.Controllers
|
||||
return dbResult;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Stored manutenzione del DB
|
||||
/// </summary>
|
||||
/// <param name="doExec">Esegue realmente il task</param>
|
||||
/// <param name="doUpdStat">Aggiornamento statistiche</param>
|
||||
/// <param name="doSave">Salvataggio</param>
|
||||
/// <param name="minPgCnt">def: 1000</param>
|
||||
/// <param name="minAvgFrag">def: 10</param>
|
||||
/// <param name="maxAvgFragReb">def: 50</param>
|
||||
/// <returns></returns>
|
||||
public async Task<bool> 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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Elenco giacenze
|
||||
/// </summary>
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
// <Auto-Generated>
|
||||
// This is here so CodeMaid doesn't reorganize this document
|
||||
// </Auto-Generated>
|
||||
namespace MP.Data.DTO
|
||||
{
|
||||
public class StatDedupDTO
|
||||
{
|
||||
/// <summary>
|
||||
/// Macchina
|
||||
/// </summary>
|
||||
public string IdxMacchina { get; set; } = "";
|
||||
|
||||
/// <summary>
|
||||
/// Cod Flusso interessato
|
||||
/// </summary>
|
||||
public string CodFlux { get; set; } = "";
|
||||
|
||||
/// <summary>
|
||||
/// Tipo di intervallo richiesto
|
||||
/// </summary>
|
||||
public Enum.DataInterval Interval { get; set; } = Enum.DataInterval.hour;
|
||||
|
||||
/// <summary>
|
||||
/// num max di item per intervallo
|
||||
/// </summary>
|
||||
public int Num4Int { get; set; } = 1;
|
||||
|
||||
/// <summary>
|
||||
/// Num record processati (iniziali)
|
||||
/// </summary>
|
||||
public int NumRec { get; set; } = 1;
|
||||
|
||||
/// <summary>
|
||||
/// Tempo processing (secondi)
|
||||
/// </summary>
|
||||
public double ProcTime { get; set; } = 1;
|
||||
|
||||
/// <summary>
|
||||
/// Tempo processing atteso in ms per record
|
||||
/// </summary>
|
||||
[NotMapped]
|
||||
public double ProcTimeMs
|
||||
{
|
||||
get => (ProcTime * 1000) / (NumRec > 1 ? NumRec : 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
using System;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
|
||||
#nullable disable
|
||||
// <Auto-Generated>
|
||||
// This is here so CodeMaid doesn't reorganize this document
|
||||
// </Auto-Generated>
|
||||
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;
|
||||
|
||||
/// <summary>
|
||||
/// Num record processati
|
||||
/// </summary>
|
||||
public int NumRec { get; set; } = 0;
|
||||
|
||||
/// <summary>
|
||||
/// Tempo processing (secondi)
|
||||
/// </summary>
|
||||
public double ProcTime { get; set; } = 1;
|
||||
|
||||
#endregion Public Properties
|
||||
}
|
||||
}
|
||||
+5
-5
@@ -18,13 +18,13 @@ namespace MP.Data
|
||||
/// </summary>
|
||||
First,
|
||||
/// <summary>
|
||||
/// Selezione ULTIMO valore del set
|
||||
/// </summary>
|
||||
Last,
|
||||
/// <summary>
|
||||
/// Selezione Moda (norma) = elemento centrale
|
||||
/// </summary>
|
||||
Center
|
||||
Center,
|
||||
/// <summary>
|
||||
/// Selezione ULTIMO valore del set
|
||||
/// </summary>
|
||||
Last
|
||||
}
|
||||
/// <summary>
|
||||
/// Intervallo dati (es per definizione quanti dati FluxLog tenere x intervallo
|
||||
|
||||
@@ -89,10 +89,7 @@ namespace MP.Data
|
||||
public virtual DbSet<ST_TemplateRows> DbSetStTemplateRows { get; set; }
|
||||
|
||||
public virtual DbSet<CommentiModel> DbSetCommenti { get; set; }
|
||||
public virtual DbSet<FermiNonQualModel> DbSetFNQ { get; set; }
|
||||
public virtual DbSet<LogFLDedupModel> DbSetLogFLDedup { get; set; }
|
||||
|
||||
|
||||
public virtual DbSet<FermiNonQualModel> DbSetFNQ { get; set; }
|
||||
|
||||
public virtual DbSet<vSelEventiBCodeModel> DbSetVSEB { get; set; }
|
||||
public virtual DbSet<vSelOdlModel> DbSetVSODL { get; set; }
|
||||
|
||||
@@ -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";
|
||||
|
||||
@@ -18,6 +18,8 @@ namespace MP.SPEC.Components
|
||||
|
||||
[Parameter]
|
||||
public EventCallback<int> E_TotalCount { get; set; }
|
||||
[Parameter]
|
||||
public EventCallback<int> 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
|
||||
|
||||
|
||||
@@ -691,6 +691,24 @@ namespace MP.SPEC.Data
|
||||
return answ;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Funzione di Data Reduction x FluxLog
|
||||
/// </summary>
|
||||
/// <param name="idxMaccSel">Macchina</param>
|
||||
/// <param name="fluxList">Elenco FL da processare</param>
|
||||
/// <param name="currPeriodo">Periodo</param>
|
||||
/// <param name="valMode">modalità sel valore</param>
|
||||
/// <param name="intReq">intervallo di analisi</param>
|
||||
/// <param name="maxItem">max num per intervallo</param>
|
||||
/// <returns></returns>
|
||||
public async Task FluxLogDataRedux(string idxMaccSel, List<string> fluxList, DtUtils.Periodo currPeriodo, ValSelection valMode, DataInterval intReq, int maxItem)
|
||||
{
|
||||
List<StatDedupDTO> procStats = await dbController.FluxLogDataRedux(idxMaccSel, fluxList, currPeriodo, valMode, intReq, maxItem);
|
||||
// effettuo merge statistiche...
|
||||
ProcStatMerge(procStats);
|
||||
await FlushCacheFluxLog();
|
||||
}
|
||||
|
||||
public List<FluxLogDTO> FluxLogDtoGetByFlux(string Valore)
|
||||
{
|
||||
List<FluxLogDTO> answ = new List<FluxLogDTO>();
|
||||
@@ -760,6 +778,22 @@ namespace MP.SPEC.Data
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Stored manutenzione del DB
|
||||
/// </summary>
|
||||
/// <param name="doExec">Esegue realmente il task</param>
|
||||
/// <param name="doUpdStat">Aggiornamento statistiche</param>
|
||||
/// <param name="doSave">Salvataggio</param>
|
||||
/// <param name="minPgCnt">def: 1000</param>
|
||||
/// <param name="minAvgFrag">def: 10</param>
|
||||
/// <param name="maxAvgFragReb">def: 50</param>
|
||||
/// <returns></returns>
|
||||
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();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Init ricetta
|
||||
/// </summary>
|
||||
@@ -1416,6 +1450,27 @@ namespace MP.SPEC.Data
|
||||
return dbResult;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Restituisce le statistiche di processo correnti x depluplica FluxLog
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public List<StatDedupDTO> ProcFLStats()
|
||||
{
|
||||
List<StatDedupDTO> actStats = new List<StatDedupDTO>();
|
||||
string currKey = $"{Utils.redisStatsProcFL}";
|
||||
// recupero i record statistiche correnti
|
||||
RedisValue rawData = redisDb.StringGet(currKey);
|
||||
if (rawData.HasValue)
|
||||
{
|
||||
var rawStats = JsonConvert.DeserializeObject<List<StatDedupDTO>>($"{rawData}");
|
||||
if (rawStats != null)
|
||||
{
|
||||
actStats = rawStats;
|
||||
}
|
||||
}
|
||||
return actStats;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Ricerca ricetta su MongoDB dato PODL
|
||||
/// </summary>
|
||||
@@ -1711,6 +1766,45 @@ namespace MP.SPEC.Data
|
||||
return TimeSpan.FromMinutes(rndValue);
|
||||
}
|
||||
|
||||
protected bool ProcStatMerge(List<StatDedupDTO> procStats)
|
||||
{
|
||||
bool answ = false;
|
||||
List<StatDedupDTO> 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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Funzione di Data Reduction x FluxLog
|
||||
/// </summary>
|
||||
/// <param name="idxMaccSel"></param>
|
||||
/// <param name="fluxList"></param>
|
||||
/// <param name="currPeriodo"></param>
|
||||
/// <param name="valMode"></param>
|
||||
/// <param name="intReq"></param>
|
||||
/// <returns></returns>
|
||||
public async Task FluxLogDataRedux(string idxMaccSel, List<string> fluxList, DtUtils.Periodo currPeriodo, ValSelection valMode, DataInterval intReq)
|
||||
{
|
||||
await dbController.FluxLogDataRedux(idxMaccSel, fluxList, currPeriodo, valMode, intReq);
|
||||
await FlushCacheFluxLog();
|
||||
}
|
||||
|
||||
#endregion Private Methods
|
||||
}
|
||||
}
|
||||
@@ -5,7 +5,7 @@
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<RootNamespace>MP.SPEC</RootNamespace>
|
||||
<Version>6.16.2310.2112</Version>
|
||||
<Version>6.16.2310.2320</Version>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
<div class="card mb-5">
|
||||
<div class="card-header">
|
||||
<div class="row">
|
||||
<div class="col-4">
|
||||
<h3>FluxLogStatus</h3>
|
||||
<div class="col-2">
|
||||
<h3>Status</h3>
|
||||
</div>
|
||||
<div class="col-4">
|
||||
<div class="input-group ">
|
||||
@@ -25,42 +25,40 @@
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-4">
|
||||
<div class="col-6">
|
||||
<PeriodoSel CurrPeriodo="@CurrPeriodo" E_PeriodoSel="SetPeriodo"></PeriodoSel>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
|
||||
@if (isProcessing)
|
||||
{
|
||||
<ProgressDisplay CurrVal="@countFlux" MaxVal="numFlux" ExpTimeMSec="@expTimeMsec"></ProgressDisplay>
|
||||
<ProgressDisplay RefreshInterval="200" Title="Data Maintenance" MaxVal="@MaxVal" CurrVal="@currVal" NextVal="@nextVal" ExpTimeMSec="@expTimeMsec"></ProgressDisplay>
|
||||
<LoadingData DisplaySize="LoadingData.CtrlSize.Large" DisplayMode="LoadingData.SpinMode.Growl"></LoadingData>
|
||||
}
|
||||
else if (isReindexing)
|
||||
{
|
||||
<LoadingData DisplaySize="LoadingData.CtrlSize.Large" DisplayMode="LoadingData.SpinMode.BounceLine"></LoadingData>
|
||||
}
|
||||
else
|
||||
{
|
||||
<FLStatusList CurrPeriodo="@CurrPeriodo" IdxMaccSel="@idxMaccSel" NumRecPage="numRecPage" PageNum="pageNum" E_TotalCount="SetTotCount" E_FluxSel="SaveFluxList"></FLStatusList>
|
||||
<FLStatusList CurrPeriodo="@CurrPeriodo" IdxMaccSel="@idxMaccSel" NumRecPage="numRecPage" PageNum="pageNum" E_TotalCount="SetTotCount" E_TotalRec="SetTotRec" E_FluxSel="SaveFluxList"></FLStatusList>
|
||||
<EgwCoreLib.Razor.DataPager currPage="@pageNum" PageSize="@numRecPage" totalCount="@totalCount" numPageChanged="SavePage" numRecordChanged="SaveNumRec"></EgwCoreLib.Razor.DataPager>
|
||||
}
|
||||
</div>
|
||||
<div class="card-footer">
|
||||
<div class="row">
|
||||
<div class="col-4">
|
||||
Selezione parametri Cleanup
|
||||
</div>
|
||||
<div class="col-2">
|
||||
<div class="input-group">
|
||||
<span class="input-group-text">Var</span>
|
||||
<select class="form-select text-end" @bind="ValMode">
|
||||
@foreach (var item in Enum.GetValues(typeof(MP.Data.Enum.ValSelection)).Cast<MP.Data.Enum.ValSelection>())
|
||||
{
|
||||
<option value="@item">@item</option>
|
||||
}
|
||||
</select>
|
||||
<div>
|
||||
Cleanup: <b>@strPrTimeExp</b> <small>(stimato)</small>
|
||||
</div>
|
||||
<div class="small">last exec: @lastExecTime</div>
|
||||
</div>
|
||||
<div class="col-2">
|
||||
<div class="input-group">
|
||||
<span class="input-group-text">Intervallo</span>
|
||||
<span class="input-group-text">Max</span>
|
||||
<input class="form-control" type="number" @bind="@NumItem" />
|
||||
<select class="form-select text-end" @bind="IntReq">
|
||||
@foreach (var item in Enum.GetValues(typeof(MP.Data.Enum.DataInterval)).Cast<MP.Data.Enum.DataInterval>())
|
||||
{
|
||||
@@ -69,8 +67,22 @@
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-2">
|
||||
<div class="input-group">
|
||||
<span class="input-group-text">Sel</span>
|
||||
<select class="form-select text-end" @bind="ValMode">
|
||||
@foreach (var item in Enum.GetValues(typeof(MP.Data.Enum.ValSelection)).Cast<MP.Data.Enum.ValSelection>())
|
||||
{
|
||||
<option value="@item">@item</option>
|
||||
}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-4">
|
||||
<button class="btn btn-warning w-100" title="Data Cleanup" @onclick="DoCleanup"><i class="fa-solid fa-broom"></i> Data Cleanup</button>
|
||||
<div class="btn-group w-100">
|
||||
<button class="btn btn-danger w-100" title="Data Cleanup" @onclick="DoCleanup"><i class="fa-solid fa-broom"></i> Data Cleanup</button>
|
||||
<button class="btn btn-warning w-100" title="Data Cleanup" @onclick="IdxRebuild"><i class="fa-solid fa-database"></i> Maint</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
using global::Microsoft.AspNetCore.Components;
|
||||
using Microsoft.JSInterop;
|
||||
using MP.SPEC.Data;
|
||||
using NLog;
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using static EgwCoreLib.Utils.DtUtils;
|
||||
using static MP.Data.Enum;
|
||||
|
||||
@@ -11,29 +12,109 @@ namespace MP.SPEC.Pages
|
||||
{
|
||||
#region Protected Fields
|
||||
|
||||
protected DataInterval IntReq = DataInterval.hour;
|
||||
protected int numRecPage = 10;
|
||||
protected int pageNum = 1;
|
||||
protected int totalCount = 0;
|
||||
protected int totRecords = 0;
|
||||
|
||||
protected ValSelection ValMode = ValSelection.First;
|
||||
|
||||
#endregion Protected Fields
|
||||
|
||||
#region Protected Properties
|
||||
|
||||
protected Dictionary<string, string> ListMacchineAll { get; set; } = new Dictionary<string, string>();
|
||||
protected List<string> fluxList { get; set; } = new List<string>();
|
||||
|
||||
[Inject]
|
||||
protected IJSRuntime JSRuntime { get; set; } = null!;
|
||||
|
||||
protected Dictionary<string, string> ListMacchineAll { get; set; } = new Dictionary<string, string>();
|
||||
|
||||
[Inject]
|
||||
protected MpDataService MDataServ { get; set; } = null!;
|
||||
|
||||
protected int NumItem
|
||||
{
|
||||
get => numItem;
|
||||
set
|
||||
{
|
||||
if (numItem != value)
|
||||
{
|
||||
// controllo valori ammissibili
|
||||
numItem = value >= 1 ? value : 1;
|
||||
// aggiorno tempi
|
||||
updateExpTime();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion Protected Properties
|
||||
|
||||
#region Protected Methods
|
||||
|
||||
/// <summary>
|
||||
/// Esegue cleanup dati
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
protected async Task DoCleanup()
|
||||
{
|
||||
if (!await JSRuntime.InvokeAsync<bool>("confirm", "Attenzione! il task di Data Cleanup eliminerà in modo definitivo i dati in eccesso secondo lo schema impostato, sei sicuro di voler procedere?"))
|
||||
return;
|
||||
|
||||
|
||||
isProcessing = true;
|
||||
lastExecTime = "...";
|
||||
Stopwatch sw = Stopwatch.StartNew();
|
||||
int currStep = 1;
|
||||
int stepVal = 1;
|
||||
foreach (var item in fluxList)
|
||||
{
|
||||
// aggiorno valori
|
||||
currVal = (currStep - 1) * stepVal;
|
||||
nextVal = currStep * stepVal;
|
||||
await InvokeAsync(StateHasChanged);
|
||||
// processo i flussi 1:1 x mandare update ad avanzamento
|
||||
await MDataServ.FluxLogDataRedux(idxMaccSel, new List<string> { item }, CurrPeriodo, ValMode, IntReq, NumItem);
|
||||
currStep++;
|
||||
}
|
||||
//await MDataServ.FluxLogDataRedux(idxMaccSel, fluxList, CurrPeriodo, ValMode, IntReq, maxItem);
|
||||
sw.Stop();
|
||||
lastExecTime = $"{sw.Elapsed.Minutes}m {sw.Elapsed.Seconds}s";
|
||||
isProcessing = false;
|
||||
}
|
||||
|
||||
protected string lastExecTime = "";
|
||||
|
||||
/// <summary>
|
||||
/// Esegue cleanup dati
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
protected async Task IdxRebuild()
|
||||
{
|
||||
if (!await JSRuntime.InvokeAsync<bool>("confirm", "Manutenzione Database: si tratta di un operazione che può richiedere un tempo levato sei sicuro di voler procedere?"))
|
||||
return;
|
||||
|
||||
isReindexing = true;
|
||||
await InvokeAsync(StateHasChanged);
|
||||
await MDataServ.ForceDbMaint(true, true, true, 1000, 10, 50);
|
||||
isReindexing = false;
|
||||
await InvokeAsync(StateHasChanged);
|
||||
}
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
ReloadStats();
|
||||
await ReloadData();
|
||||
}
|
||||
|
||||
private void ReloadStats()
|
||||
{
|
||||
actStats = MDataServ.ProcFLStats();
|
||||
}
|
||||
|
||||
protected List<MP.Data.DTO.StatDedupDTO> actStats { get; set; } = new List<MP.Data.DTO.StatDedupDTO>();
|
||||
|
||||
protected async Task ReloadMacchine()
|
||||
{
|
||||
if (ListMacchineAll == null || ListMacchineAll.Count == 0)
|
||||
@@ -47,6 +128,12 @@ namespace MP.SPEC.Pages
|
||||
}
|
||||
}
|
||||
|
||||
protected async Task SaveFluxList(List<string> newList)
|
||||
{
|
||||
fluxList = newList;
|
||||
await Task.Delay(1);
|
||||
}
|
||||
|
||||
protected void SaveNumRec(int newNum)
|
||||
{
|
||||
if (numRecPage != newNum)
|
||||
@@ -77,10 +164,41 @@ namespace MP.SPEC.Pages
|
||||
totalCount = numRec;
|
||||
await Task.Delay(1);
|
||||
}
|
||||
protected async Task SaveFluxList(List<string> newList)
|
||||
protected async Task SetTotRec(int numRec)
|
||||
{
|
||||
fluxList = newList;
|
||||
totRecords = numRec;
|
||||
await Task.Delay(1);
|
||||
updateExpTime();
|
||||
}
|
||||
|
||||
private void updateExpTime()
|
||||
{
|
||||
// calcolo tempo stimato e mostro...
|
||||
double msProcEst = 0.15 * numItem;
|
||||
// recupero statistiche x tipoInt e num eventi...
|
||||
var calcStats = actStats.Where(x => x.Interval == IntReq && x.Num4Int == numItem);
|
||||
//var calcStats = actStats.Where(x => x.IdxMacchina == idxMaccSel && x.Interval == IntReq && x.Num4Int == numItem);
|
||||
if (calcStats != null && calcStats.Count() > 0)
|
||||
{
|
||||
var totSec = calcStats.Sum(x => x.ProcTime);
|
||||
var totalRec = calcStats.Sum(x => x.NumRec);
|
||||
msProcEst = totSec * 1000 / (totalRec > 1 ? totalRec : 1);
|
||||
}
|
||||
int numFlux = fluxList.Count > 1 ? fluxList.Count : 1;
|
||||
expTimeMsec = (int)Math.Ceiling(msProcEst * totRecords / numFlux);
|
||||
strPrTimeExp = "-";
|
||||
if (totRecords > 0)
|
||||
{
|
||||
var TotalTime = TimeSpan.FromMilliseconds(msProcEst * totRecords);
|
||||
if (TotalTime.TotalMinutes > 60)
|
||||
{
|
||||
strPrTimeExp = $"{TotalTime.Hours}h {TotalTime.Minutes}m";
|
||||
}
|
||||
else
|
||||
{
|
||||
strPrTimeExp = $"{TotalTime.Minutes}m {TotalTime.Seconds}s";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion Protected Methods
|
||||
@@ -89,6 +207,14 @@ namespace MP.SPEC.Pages
|
||||
|
||||
private static NLog.Logger Log = LogManager.GetCurrentClassLogger();
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Tempo atteso processing
|
||||
/// - da calcolare in base al num eventi e alla tab logProcessing...
|
||||
/// </summary>
|
||||
private int expTimeMsec = 3000;
|
||||
|
||||
#endregion Private Fields
|
||||
|
||||
#region Private Properties
|
||||
@@ -97,6 +223,17 @@ namespace MP.SPEC.Pages
|
||||
|
||||
private string idxMaccSel { get; set; } = "";
|
||||
private bool isProcessing { get; set; } = false;
|
||||
private bool isReindexing { get; set; } = false;
|
||||
|
||||
|
||||
protected double currVal = 0;
|
||||
protected double nextVal = 0;
|
||||
protected int MaxVal
|
||||
{
|
||||
get => fluxList.Count;
|
||||
}
|
||||
|
||||
private int numItem { get; set; } = 1;
|
||||
|
||||
#endregion Private Properties
|
||||
|
||||
@@ -108,33 +245,13 @@ namespace MP.SPEC.Pages
|
||||
DateTime dtEnd = DateTime.Today.AddDays(1);
|
||||
DateTime dtStart = dtEnd.AddMonths(-1);
|
||||
CurrPeriodo = new Periodo(dtStart, dtEnd);
|
||||
}
|
||||
/// <summary>
|
||||
/// Esegue cleanup dati
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
protected async Task DoCleanup()
|
||||
{
|
||||
isProcessing = true;
|
||||
// processo i flussi in subset x mandare update ad avanzamento
|
||||
await MDataServ.FluxLogDataRedux(idxMaccSel, fluxList, CurrPeriodo, ValMode, IntReq);
|
||||
isProcessing = false;
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tempo atteso processing
|
||||
/// - da calcolare in abse al num eventi e alla tab logProcessing...
|
||||
/// </summary>
|
||||
private int expTimeMsec = 10000;
|
||||
private int countFlux = 0;
|
||||
private int numFlux
|
||||
{
|
||||
get => fluxList.Count * 10;
|
||||
}
|
||||
|
||||
protected ValSelection ValMode = ValSelection.Center;
|
||||
protected DataInterval IntReq = DataInterval.hour;
|
||||
private double msProcEst { get; set; } = 0.2;
|
||||
|
||||
protected string strPrTimeExp { get; set; } = "-";
|
||||
|
||||
#endregion Private Methods
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
<body>
|
||||
<i>Modulo MAPOSPEC </i>
|
||||
<h4>Versione: 6.16.2310.2112</h4>
|
||||
<h4>Versione: 6.16.2310.2320</h4>
|
||||
<br /> Note di rilascio:
|
||||
<ul>
|
||||
<li>
|
||||
|
||||
@@ -1 +1 @@
|
||||
6.16.2310.2112
|
||||
6.16.2310.2320
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<item>
|
||||
<version>6.16.2310.2112</version>
|
||||
<version>6.16.2310.2320</version>
|
||||
<url>https://nexus.steamware.net/repository/SWS/MP-SPEC/stable/LAST/MP.SPEC.zip</url>
|
||||
<changelog>https://nexus.steamware.net/repository/SWS/MP-SPEC/stable/LAST/ChangeLog.html</changelog>
|
||||
<mandatory>false</mandatory>
|
||||
|
||||
Reference in New Issue
Block a user