Merge branch 'Release/UpdateIoC_01'
This commit is contained in:
@@ -1060,24 +1060,40 @@ namespace MP.Data.Controllers
|
||||
{
|
||||
bool fatto = false;
|
||||
using var dbCtx = new MoonProContext(_configuration);
|
||||
using var transaction = await dbCtx.Database.BeginTransactionAsync();
|
||||
|
||||
// 1. Transazione minima: SOLO INSERT + COMMIT
|
||||
await using var tx = await dbCtx.Database.BeginTransactionAsync();
|
||||
try
|
||||
{
|
||||
dbCtx.DbSetRemRebLog.Add(newRec);
|
||||
fatto = await dbCtx.SaveChangesAsync() > 0;
|
||||
|
||||
|
||||
var param = new SqlParameter("@num2keep", num2keep);
|
||||
await dbCtx.Database.ExecuteSqlRawAsync("EXEC dbo.stp_RRL_KeepLatest @num2keep", param);
|
||||
|
||||
await transaction.CommitAsync();
|
||||
return true;
|
||||
await tx.CommitAsync(); // 🔑 Commit prima della pulizia
|
||||
}
|
||||
catch
|
||||
{
|
||||
await transaction.RollbackAsync();
|
||||
await tx.RollbackAsync();
|
||||
throw;
|
||||
}
|
||||
|
||||
// 2. Cleanup "smart" fuori transazione
|
||||
if (fatto)
|
||||
{
|
||||
try
|
||||
{
|
||||
var param = new SqlParameter("@num2keep", num2keep);
|
||||
await dbCtx.Database.ExecuteSqlRawAsync(
|
||||
"EXEC dbo.stp_RRL_KeepLatest @num2keep, @multiplier", param,
|
||||
new SqlParameter("@multiplier", 1.3f)); // Fisso o leggo da config
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// Log dell'errore, ma NON rilanciare: il record è già salvo
|
||||
Log.Error(ex, "Failed to execute RRL cleanup for {Machine}", newRec.IdxMacchina);
|
||||
}
|
||||
}
|
||||
|
||||
return fatto;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -1119,10 +1135,11 @@ namespace MP.Data.Controllers
|
||||
{
|
||||
using var dbCtx = new MoonProContext(_configuration);
|
||||
|
||||
var Num2keep = new SqlParameter("@num2keep", num2keep);
|
||||
var dbResult = await dbCtx
|
||||
.Database
|
||||
.ExecuteSqlRawAsync("exec dbo.stp_RRL_KeepLatest @num2keep", Num2keep);
|
||||
var pNum2Keep = new SqlParameter("@num2keep", num2keep);
|
||||
// La SP gestisce già la logica di soglia (1.5x), ma la specifico x sicurezza
|
||||
var pThresh = new SqlParameter("@threshMult", 1.5);
|
||||
var dbResult = await dbCtx.Database.ExecuteSqlRawAsync(
|
||||
"EXEC dbo.stp_RRL_KeepLatest @num2keep, @threshMult", pNum2Keep, pThresh);
|
||||
|
||||
return dbResult != 0;
|
||||
}
|
||||
|
||||
@@ -1156,7 +1156,6 @@ namespace MP.IOC.Controllers
|
||||
// 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();
|
||||
|
||||
// chiamo registrazione reboot
|
||||
@@ -1187,7 +1186,6 @@ namespace MP.IOC.Controllers
|
||||
Log.Error($"Errore in sendReboot{Environment.NewLine}{exc}");
|
||||
return StatusCode(StatusCodes.Status500InternalServerError, "NO");
|
||||
}
|
||||
return Ok(answ);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -2945,6 +2945,25 @@ namespace MP.IOC.Data
|
||||
return answ;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Formato dataora standard x parsing
|
||||
/// </summary>
|
||||
private string dtFormat = "yyyyMMddHHmmssfff";
|
||||
/// <summary>
|
||||
/// Provider CultureInfo x parse valori (es dataora)
|
||||
/// </summary>
|
||||
private CultureInfo ciProvider = CultureInfo.InvariantCulture;
|
||||
|
||||
/// <summary>
|
||||
/// Helper standardizzazione valore dataora ricevuto da IOB remoti
|
||||
/// </summary>
|
||||
/// <param name="s"></param>
|
||||
/// <returns></returns>
|
||||
private string dtFormStd(string? s)
|
||||
{
|
||||
return s?.Length > 17 ? s[..17] : s?.PadRight(17, '0') ?? string.Empty;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Processa input da IOB eventualmente registrando i segnali inviati
|
||||
/// </summary>
|
||||
@@ -2968,68 +2987,41 @@ namespace MP.IOC.Data
|
||||
}
|
||||
else
|
||||
{
|
||||
// 2017.09.14 trimmo eventualmente lo zero finale dalle date SE supera i millisecondi...
|
||||
dtEve = dtEve.Length > 17 ? dtEve.Substring(0, 17) : dtEve;
|
||||
dtCurr = dtCurr.Length > 17 ? dtCurr.Substring(0, 17) : dtCurr;
|
||||
|
||||
DateTime dataOraEvento = DateTime.Now;
|
||||
DateTime dtEvento, dtCorrente;
|
||||
// controllo: se ho valori dt x evento e orario DIVERSI per acquisitore IOB calcolo
|
||||
// dataOraEvento corretto
|
||||
if (dtEve != dtCurr)
|
||||
|
||||
// fix formato dataora in ingresso
|
||||
string stdEve = dtFormStd(dtEve);
|
||||
string stdCurr = dtFormStd(dtCurr);
|
||||
|
||||
// 2. Se le stringhe normalizzate coincidono, skip dei calcoli
|
||||
if (stdEve != stdCurr)
|
||||
{
|
||||
// delta è un calcolo MOLTO approssimativo della differenza temporale...
|
||||
Int64 delta = 0;
|
||||
try
|
||||
|
||||
// 3. Parsing sicuro
|
||||
if (DateTime.TryParseExact(stdEve, dtFormat, ciProvider, DateTimeStyles.None, out DateTime dtEvento) &&
|
||||
DateTime.TryParseExact(stdCurr, dtFormat, ciProvider, DateTimeStyles.None, out DateTime dtCorrente))
|
||||
{
|
||||
// se ho meno decimali x evento rispetto dtCorrente...
|
||||
if (dtEve.Length < dtCurr.Length)
|
||||
TimeSpan diff = dtCorrente - dtEvento;
|
||||
double ms = Math.Abs(diff.TotalMilliseconds);
|
||||
|
||||
// 4. Classificazione delta con switch expression (più leggibile e performante)
|
||||
string deltaClass = ms switch
|
||||
{
|
||||
Log.Info($"ProcessInputAsync: fix valore dtEve: {dtEve} | dtCurr: {dtCurr}");
|
||||
dtEve = dtEve.PadRight(dtCurr.Length, '0');
|
||||
}
|
||||
delta = Convert.ToInt64(dtCurr) - Convert.ToInt64(dtEve);
|
||||
// log della classe del delta (1-10, 10-100, 100-1k, 1k-10k, > 10k ms)
|
||||
string deltaClass = "";
|
||||
// faccio SEMPRE calcolo esatto sennò sbaglia...
|
||||
CultureInfo provider = CultureInfo.InvariantCulture;
|
||||
string format = "yyyyMMddHHmmssfff";
|
||||
dtEvento = DateTime.ParseExact(dtEve, format, provider);
|
||||
dtCorrente = DateTime.ParseExact(dtCurr, format, provider);
|
||||
Int64 tiks = dtCorrente.Ticks - dtEvento.Ticks;
|
||||
TimeSpan ts = new TimeSpan(tiks);
|
||||
double ms = Math.Abs(ts.TotalMilliseconds);
|
||||
// calcolo ESATTO dataora evento
|
||||
dataOraEvento = dataOraEvento.AddTicks(-tiks);
|
||||
if (ms <= 10)
|
||||
{
|
||||
deltaClass = "delta 0-10 ms";
|
||||
}
|
||||
else if (ms <= 100)
|
||||
{
|
||||
deltaClass = "delta 10-100 ms";
|
||||
}
|
||||
else if (ms <= 1000)
|
||||
{
|
||||
deltaClass = "delta 100-1000 ms";
|
||||
}
|
||||
else if (ms <= 10000)
|
||||
{
|
||||
deltaClass = "delta 1-10 sec";
|
||||
}
|
||||
else
|
||||
{
|
||||
deltaClass = "delta > 10 sec";
|
||||
}
|
||||
// se ho deltaClass loggo
|
||||
if (deltaClass != "")
|
||||
{
|
||||
Log.Debug("Correzione " + deltaClass);
|
||||
}
|
||||
<= 10 => "0-10 ms",
|
||||
<= 100 => "10-100 ms",
|
||||
<= 1000 => "100-1000 ms",
|
||||
<= 10000 => "1-10 sec",
|
||||
_ => "> 10 sec"
|
||||
};
|
||||
|
||||
Log.Debug($"Correzione delta {deltaClass}");
|
||||
|
||||
// 5. Correzione data/ora server: sottrao lo scarto calcolato
|
||||
dataOraEvento = dataOraEvento.Subtract(diff);
|
||||
}
|
||||
catch (Exception exc)
|
||||
else
|
||||
{
|
||||
Log.Error($"Errore calcolo ms evento/ora corrente da device remoto | dtEve: {dtEve} | dtCurr: {dtCurr}{Environment.NewLine}{exc}");
|
||||
Log.Error($"Errore parsing date: {stdEve} | {stdCurr}");
|
||||
}
|
||||
}
|
||||
// inizio processing vero e proprio INPUT...
|
||||
@@ -4563,8 +4555,10 @@ namespace MP.IOC.Data
|
||||
int.TryParse(datiMacc.ContainsKey("BitFilt") ? datiMacc["BitFilt"] : "0", out BitFilt);
|
||||
int.TryParse(datiMacc.ContainsKey("BSR") ? datiMacc["BSR"] : "0", out BSR);
|
||||
Boolean.TryParse(datiMacc.ContainsKey("ExplodeBit") ? datiMacc["ExplodeBit"] : "false", out ExplodeBit);
|
||||
int.TryParse(datiMacc.ContainsKey("NumBit") ? datiMacc["NumBit"] : "0", out NumBit); // non usato (x ora)
|
||||
// recupero valore
|
||||
// non usato (x ora)
|
||||
int.TryParse(datiMacc.ContainsKey("NumBit") ? datiMacc["NumBit"] : "0", out NumBit);
|
||||
|
||||
// recupero valore
|
||||
valINT = int.Parse(valore, NumberStyles.HexNumber);
|
||||
// filtro
|
||||
newValInt = MP.Core.Utils.bMaskInt(valINT, BitFilt);
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Version>8.16.2604.2718</Version>
|
||||
<Version>8.16.2604.2808</Version>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<body>
|
||||
<i>Modulo MP-IOC </i>
|
||||
<h4>Versione: 8.16.2604.2718</h4>
|
||||
<h4>Versione: 8.16.2604.2808</h4>
|
||||
<br /> Note di rilascio:
|
||||
<ul>
|
||||
<li>
|
||||
|
||||
@@ -1 +1 @@
|
||||
8.16.2604.2718
|
||||
8.16.2604.2808
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<item>
|
||||
<version>8.16.2604.2718</version>
|
||||
<version>8.16.2604.2808</version>
|
||||
<url>https://nexus.steamware.net/repository/SWS/MP-IOC/stable/LAST/MP.IOC.zip</url>
|
||||
<changelog>https://nexus.steamware.net/repository/SWS/MP-IOC/stable/LAST/ChangeLog.html</changelog>
|
||||
<mandatory>false</mandatory>
|
||||
|
||||
Reference in New Issue
Block a user