This commit is contained in:
zaccaria.majid
2023-10-24 16:12:19 +02:00
11 changed files with 242 additions and 84 deletions
+4 -3
View File
@@ -724,9 +724,10 @@ namespace MP.Data.Controllers
/// <returns></returns>
public async Task<bool> ForceDbMaint(bool doExec, bool doUpdStat, bool doSave, int minPgCnt, int minAvgFrag, int maxAvgFragReb)
{
Log.Info($"Inizio ForceDbMaint");
Log.Info($"Inizio ForceDbMaint on MoonProAdminContext");
bool fatto = false;
using (var dbCtx = new MoonProContext(_configuration))
// uso context admin x query lunghe
using (var dbCtx = new MoonProAdminContext(_configuration))
{
var pFlgExec = new SqlParameter("@FlgExec", doExec ? "Y" : "N");
var pFlgUpdStat = new SqlParameter("@FlgUpdStat", doUpdStat ? "Y" : "N");
@@ -741,7 +742,7 @@ namespace MP.Data.Controllers
//.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");
Log.Info($"FINE ForceDbMaint on MoonProAdminContext");
return fatto;
}
+1 -1
View File
@@ -20,7 +20,7 @@
<ItemGroup>
<PackageReference Include="Blazored.LocalStorage" Version="4.3.0" />
<PackageReference Include="Blazored.SessionStorage" Version="2.4.0" />
<PackageReference Include="EgwCoreLib.Utils" Version="1.4.2310.1312" />
<PackageReference Include="EgwCoreLib.Utils" Version="1.4.2310.2409" />
<PackageReference Include="MailKit" Version="4.2.0" />
<PackageReference Include="Microsoft.AspNetCore.Http.Features" Version="5.0.17" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="6.0.9" />
+75
View File
@@ -0,0 +1,75 @@
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.Extensions.Configuration;
using MP.Data.DatabaseModels;
using MP.Data.DTO;
using NLog;
#nullable disable
// <Auto-Generated>
// This is here so CodeMaid doesn't reorganize this document
// </Auto-Generated>
namespace MP.Data
{
public partial class MoonProAdminContext : DbContext
{
#region Private Fields
private static NLog.Logger Log = LogManager.GetCurrentClassLogger();
private IConfiguration _configuration;
#endregion Private Fields
#region Public Constructors
public MoonProAdminContext(IConfiguration configuration)
{
_configuration = configuration;
// timeout esecuzione a 5 min (std: 30 sec)...
Database.SetCommandTimeout(TimeSpan.FromSeconds(300));
}
public MoonProAdminContext(DbContextOptions<MoonProAdminContext> options) : base(options)
{
}
#endregion Public Constructors
#region Private Methods
partial void OnModelCreatingPartial(ModelBuilder modelBuilder);
#endregion Private Methods
#region Protected Methods
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
if (!optionsBuilder.IsConfigured)
{
string connString = _configuration.GetConnectionString("Mp.Data");
if (string.IsNullOrEmpty(connString))
{
connString = _configuration.GetConnectionString("Mp.Mon");
}
if (string.IsNullOrEmpty(connString))
{
connString = _configuration.GetConnectionString("Mp.STATS");
}
optionsBuilder.UseSqlServer(connString);
}
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.HasAnnotation("Relational:Collation", "SQL_Latin1_General_CP1_CI_AS");
OnModelCreatingPartial(modelBuilder);
}
#endregion Protected Methods
}
}
+1
View File
@@ -233,6 +233,7 @@ namespace MP.Data
public const string redisAKVKey = redisBaseAddr + "Cache:AKV";
public const string redisParetoFLKey = redisBaseAddr + "Cache:ParetoFL";
public const string redisStatsProcFL = redisBaseAddr + "Stats:ProcessFL";
public const string redisStatsDbMaint = redisBaseAddr + "Stats:DbMaint";
public const string redisDossByMac = redisBaseAddr + "Cache:DossByMac";
public const string redisFluxByMac = redisBaseAddr + "Cache:FluxByMac";
public const string redisFluxLogFilt = redisBaseAddr + "Cache:FluxLogFilt";
+52 -2
View File
@@ -453,6 +453,27 @@ namespace MP.SPEC.Data
return await Task.FromResult(dbController.ConfigUpdate(updRec));
}
/// <summary>
/// Restituisce le statistiche di DB maintenance eseguite
/// </summary>
/// <returns></returns>
public Dictionary<DateTime, double> DbDedupStats()
{
Dictionary<DateTime, double> actStats = new Dictionary<DateTime, double>();
string currKey = $"{Utils.redisStatsDbMaint}";
// recupero i record statistiche correnti
RedisValue rawData = redisDb.StringGet(currKey);
if (rawData.HasValue)
{
var rawStats = JsonConvert.DeserializeObject<Dictionary<DateTime, double>>($"{rawData}");
if (rawStats != null)
{
actStats = rawStats;
}
}
return actStats;
}
/// <summary>
/// Dispose del connettore ai dati
/// </summary>
@@ -705,7 +726,8 @@ namespace MP.SPEC.Data
{
List<StatDedupDTO> procStats = await dbController.FluxLogDataRedux(idxMaccSel, fluxList, currPeriodo, valMode, intReq, maxItem);
// effettuo merge statistiche...
ProcStatMerge(procStats);
ProcDedupStatMerge(procStats);
// svuoto cache
await FlushCacheFluxLog();
}
@@ -790,7 +812,12 @@ namespace MP.SPEC.Data
/// <returns></returns>
public async Task ForceDbMaint(bool doExec = true, bool doUpdStat = true, bool doSave = true, int minPgCnt = 1000, int minAvgFrag = 10, int maxAvgFragReb = 50)
{
Stopwatch sw = Stopwatch.StartNew();
await dbController.ForceDbMaint(doExec, doUpdStat, doSave, minPgCnt, minAvgFrag, maxAvgFragReb);
sw.Stop();
// registro statistiche esecuzione
RecDbMaintStat(sw.Elapsed);
// svuoto cache
await FlushCacheFluxLog();
}
@@ -1766,7 +1793,12 @@ namespace MP.SPEC.Data
return TimeSpan.FromMinutes(rndValue);
}
protected bool ProcStatMerge(List<StatDedupDTO> procStats)
/// <summary>
/// Merge statistiche Dedup
/// </summary>
/// <param name="procStats"></param>
/// <returns></returns>
protected bool ProcDedupStatMerge(List<StatDedupDTO> procStats)
{
bool answ = false;
List<StatDedupDTO> actStats = ProcFLStats();
@@ -1805,6 +1837,24 @@ namespace MP.SPEC.Data
return answ;
}
/// <summary>
/// Merge statistiche DB Maintenance
/// </summary>
/// <param name="procStats"></param>
/// <returns></returns>
protected bool RecDbMaintStat(TimeSpan duration)
{
bool answ = false;
Dictionary<DateTime, double> actStats = DbDedupStats();
// aggiungo record!
actStats.Add(DateTime.Now, duration.TotalSeconds);
// salvo NUOVO record statistiche
string currKey = $"{Utils.redisStatsDbMaint}";
var rawData = JsonConvert.SerializeObject(actStats);
redisDb.StringSet(currKey, rawData);
return answ;
}
#endregion Protected Methods
#region Private Fields
+3 -3
View File
@@ -5,7 +5,7 @@
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<RootNamespace>MP.SPEC</RootNamespace>
<Version>6.16.2310.2320</Version>
<Version>6.16.2310.2409</Version>
</PropertyGroup>
<ItemGroup>
@@ -39,8 +39,8 @@
<ItemGroup>
<PackageReference Include="Blazored.LocalStorage" Version="4.3.0" />
<PackageReference Include="Blazored.SessionStorage" Version="2.4.0" />
<PackageReference Include="EgwCoreLib.Razor" Version="1.4.2310.1312" />
<PackageReference Include="EgwCoreLib.Utils" Version="1.4.2310.1312" />
<PackageReference Include="EgwCoreLib.Razor" Version="1.4.2310.2409" />
<PackageReference Include="EgwCoreLib.Utils" Version="1.4.2310.2409" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.Negotiate" Version="6.0.9" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
</ItemGroup>
+17 -7
View File
@@ -35,11 +35,11 @@
@if (isProcessing)
{
<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>
<LoadingData Title="Cleaning Up Data" DisplaySize="LoadingData.CtrlSize.Large" DisplayMode="LoadingData.SpinMode.Growl"></LoadingData>
}
else if (isReindexing)
{
<LoadingData DisplaySize="LoadingData.CtrlSize.Large" DisplayMode="LoadingData.SpinMode.BounceLine"></LoadingData>
<LoadingData Title="DB Maintenance running" DisplaySize="LoadingData.CtrlSize.Large" DisplayMode="LoadingData.SpinMode.BounceLine"></LoadingData>
}
else
{
@@ -49,11 +49,16 @@
</div>
<div class="card-footer">
<div class="row">
<div class="col-4">
<div class="col-2">
<div>
Cleanup: <b>@strPrTimeExp</b> <small>(stimato)</small>
Cleanup: <b>@strPrTimeExp</b> <small>(stimato)</small>
</div>
<div class="small">Ultima: @lastDedupExecTime</div>
</div>
<div class="col-2">
<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>
</div>
<div class="small">last exec: @lastExecTime</div>
</div>
<div class="col-2">
<div class="input-group">
@@ -78,12 +83,17 @@
</select>
</div>
</div>
<div class="col-4">
<div class="col-2">
<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 class="col-2">
<div>
Db Maint: <b>@strDbMaintTimeExp</b> <small>(stimato)</small>
</div>
<div class="small">Ultima: @lastDbMaintTime</div>
</div>
</div>
</div>
</div>
+86 -65
View File
@@ -12,7 +12,9 @@ namespace MP.SPEC.Pages
{
#region Protected Fields
protected double currVal = 0;
protected DataInterval IntReq = DataInterval.hour;
protected double nextVal = 0;
protected int numRecPage = 10;
protected int pageNum = 1;
protected int totalCount = 0;
@@ -24,6 +26,8 @@ namespace MP.SPEC.Pages
#region Protected Properties
protected Dictionary<DateTime, double> actDbMaintStats { get; set; } = new Dictionary<DateTime, double>();
protected List<MP.Data.DTO.StatDedupDTO> actProcDedupStats { get; set; } = new List<MP.Data.DTO.StatDedupDTO>();
protected List<string> fluxList { get; set; } = new List<string>();
[Inject]
@@ -31,6 +35,11 @@ namespace MP.SPEC.Pages
protected Dictionary<string, string> ListMacchineAll { get; set; } = new Dictionary<string, string>();
protected int MaxVal
{
get => fluxList.Count;
}
[Inject]
protected MpDataService MDataServ { get; set; } = null!;
@@ -49,6 +58,9 @@ namespace MP.SPEC.Pages
}
}
protected string strDbMaintTimeExp { get; set; } = "-";
protected string strPrTimeExp { get; set; } = "-";
#endregion Protected Properties
#region Protected Methods
@@ -62,9 +74,8 @@ namespace MP.SPEC.Pages
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 = "...";
lastDedupExecTime = "...";
Stopwatch sw = Stopwatch.StartNew();
int currStep = 1;
int stepVal = 1;
@@ -80,12 +91,10 @@ namespace MP.SPEC.Pages
}
//await MDataServ.FluxLogDataRedux(idxMaccSel, fluxList, CurrPeriodo, ValMode, IntReq, maxItem);
sw.Stop();
lastExecTime = $"{sw.Elapsed.Minutes}m {sw.Elapsed.Seconds}s";
lastDedupExecTime = $"{sw.Elapsed.Minutes}m {sw.Elapsed.Seconds}s";
isProcessing = false;
}
protected string lastExecTime = "";
/// <summary>
/// Esegue cleanup dati
/// </summary>
@@ -96,10 +105,13 @@ namespace MP.SPEC.Pages
return;
isReindexing = true;
Stopwatch sw = Stopwatch.StartNew();
lastDbMaintTime = "...";
await InvokeAsync(StateHasChanged);
await MDataServ.ForceDbMaint(true, true, true, 1000, 10, 50);
sw.Stop();
lastDbMaintTime = $"{sw.Elapsed.Minutes}m {sw.Elapsed.Seconds}s";
isReindexing = false;
await InvokeAsync(StateHasChanged);
}
protected override async Task OnInitializedAsync()
@@ -108,13 +120,6 @@ namespace MP.SPEC.Pages
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)
@@ -164,6 +169,7 @@ namespace MP.SPEC.Pages
totalCount = numRec;
await Task.Delay(1);
}
protected async Task SetTotRec(int numRec)
{
totRecords = numRec;
@@ -171,12 +177,61 @@ namespace MP.SPEC.Pages
updateExpTime();
}
#endregion Protected Methods
#region Private Fields
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;
private string lastDbMaintTime = "";
private string lastDedupExecTime = "";
#endregion Private Fields
#region Private Properties
private Periodo CurrPeriodo { get; set; } = new Periodo();
private string idxMaccSel { get; set; } = "";
private bool isProcessing { get; set; } = false;
private bool isReindexing { get; set; } = false;
private double msProcEst { get; set; } = 0.2;
private int numItem { get; set; } = 1;
#endregion Private Properties
#region Private Methods
private async Task ReloadData()
{
await ReloadMacchine();
DateTime dtEnd = DateTime.Today.AddDays(1);
DateTime dtStart = dtEnd.AddMonths(-1);
CurrPeriodo = new Periodo(dtStart, dtEnd);
}
private void ReloadStats()
{
actProcDedupStats = MDataServ.ProcFLStats();
actDbMaintStats = MDataServ.DbDedupStats();
}
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 = actProcDedupStats.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)
{
@@ -199,59 +254,25 @@ namespace MP.SPEC.Pages
strPrTimeExp = $"{TotalTime.Minutes}m {TotalTime.Seconds}s";
}
}
// ora sistemo le statistiche DB maintenance
double estimDbMaintSec = 150;
var dbTotSec = actDbMaintStats.Sum(x => x.Value);
var dbNumItem = actDbMaintStats.Count();
if (dbNumItem > 0)
{
estimDbMaintSec = dbTotSec / dbNumItem;
}
var TotalTimeDb = TimeSpan.FromSeconds(estimDbMaintSec);
if (TotalTimeDb.TotalMinutes > 60)
{
strDbMaintTimeExp = $"{TotalTimeDb.Hours}h {TotalTimeDb.Minutes}m";
}
else
{
strDbMaintTimeExp = $"{TotalTimeDb.Minutes}m {TotalTimeDb.Seconds}s";
}
}
#endregion Protected Methods
#region Private Fields
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
private Periodo CurrPeriodo { get; set; } = new Periodo();
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
#region Private Methods
private async Task ReloadData()
{
await ReloadMacchine();
DateTime dtEnd = DateTime.Today.AddDays(1);
DateTime dtStart = dtEnd.AddMonths(-1);
CurrPeriodo = new Periodo(dtStart, dtEnd);
}
private double msProcEst { get; set; } = 0.2;
protected string strPrTimeExp { get; set; } = "-";
#endregion Private Methods
}
}
+1 -1
View File
@@ -1,6 +1,6 @@
<body>
<i>Modulo MAPOSPEC </i>
<h4>Versione: 6.16.2310.2320</h4>
<h4>Versione: 6.16.2310.2409</h4>
<br /> Note di rilascio:
<ul>
<li>
+1 -1
View File
@@ -1 +1 @@
6.16.2310.2320
6.16.2310.2409
+1 -1
View File
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<item>
<version>6.16.2310.2320</version>
<version>6.16.2310.2409</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>