Aggiunta gestione salvataggio range statistiche
This commit is contained in:
@@ -4,6 +4,7 @@ using EgwCoreLib.Lux.Data.DbModel.Cost;
|
||||
using EgwCoreLib.Lux.Data.DbModel.Items;
|
||||
using EgwCoreLib.Lux.Data.DbModel.Production;
|
||||
using EgwCoreLib.Lux.Data.DbModel.Sales;
|
||||
using EgwCoreLib.Lux.Data.DbModel.Stats;
|
||||
using EgwCoreLib.Lux.Data.DbModel.Task;
|
||||
using EgwCoreLib.Lux.Data.DbModel.Utils;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
@@ -2519,7 +2520,7 @@ namespace EgwCoreLib.Lux.Data.Controllers
|
||||
/// <returns></returns>
|
||||
internal async Task<OrderModel?> OrderFromOffer(OfferModel rec2clone)
|
||||
{
|
||||
OrderModel? newRec = null;
|
||||
OrderModel? newRec = null;
|
||||
//using (DataLayerContext dbCtx = new DataLayerContext(_config))
|
||||
using (DataLayerContext dbCtx = new DataLayerContext())
|
||||
{
|
||||
@@ -2610,7 +2611,7 @@ namespace EgwCoreLib.Lux.Data.Controllers
|
||||
if (numSave > 0 && newRec != null)
|
||||
{
|
||||
#if false
|
||||
orderId = newRec.OrderID;
|
||||
orderId = newRec.OrderID;
|
||||
#endif
|
||||
// sistemo UID...
|
||||
foreach (var item in newRec.OrderRowNav)
|
||||
@@ -2660,7 +2661,7 @@ namespace EgwCoreLib.Lux.Data.Controllers
|
||||
}
|
||||
return newRec;
|
||||
#if false
|
||||
return orderId;
|
||||
return orderId;
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -3282,6 +3283,94 @@ namespace EgwCoreLib.Lux.Data.Controllers
|
||||
}
|
||||
#endif
|
||||
|
||||
/// <summary>
|
||||
/// Esegue insert statistiche aggregate sul DB
|
||||
/// </summary>
|
||||
/// <param name="listRecords">Elenco dei record da inserire</param>
|
||||
/// <param name="removeOld">Se true preventivamente elimina record nel periodo richiesto</param>
|
||||
/// <returns></returns>
|
||||
internal async Task<long> StatsAggrUpsertAsync(List<StatsAggregated> listRecords, bool removeOld)
|
||||
{
|
||||
int answ = 0;
|
||||
//using (DataLayerContext dbCtx = new DataLayerContext(_config))
|
||||
using (DataLayerContext dbCtx = new DataLayerContext())
|
||||
{
|
||||
// in primis se richiesto calcolo range periodo e svuoto...
|
||||
if (removeOld)
|
||||
{
|
||||
var firstRec = listRecords.OrderBy(x => x.Hour).FirstOrDefault();
|
||||
var lastRec = listRecords.OrderByDescending(x => x.Hour).FirstOrDefault();
|
||||
|
||||
if (firstRec != null && lastRec != null)
|
||||
{
|
||||
DateTime startDate = firstRec.Hour;
|
||||
DateTime endDate = lastRec.Hour;
|
||||
// uso direttamente ExecuteDelete
|
||||
await dbCtx
|
||||
.DbSetStatsAggr
|
||||
.Where(x => x.Hour >= startDate && x.Hour < endDate)
|
||||
.ExecuteDeleteAsync();
|
||||
}
|
||||
}
|
||||
|
||||
// ora preparo inserimento massivo
|
||||
await dbCtx
|
||||
.DbSetStatsAggr
|
||||
.AddRangeAsync(listRecords);
|
||||
|
||||
// salvo!
|
||||
answ = await dbCtx.SaveChangesAsync();
|
||||
|
||||
// libero memoria del changeTracker
|
||||
dbCtx.ChangeTracker.Clear();
|
||||
}
|
||||
return answ;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Esegue insert statistiche di dettaglio sul DB
|
||||
/// </summary>
|
||||
/// <param name="listRecords">Elenco dei record da inserire</param>
|
||||
/// <param name="removeOld">Se true preventivamente elimina record nel periodo richiesto</param>
|
||||
/// <returns></returns>
|
||||
internal async Task<long> StatsDetailUpsertAsync(List<StatsDetail> listRecords, bool removeOld)
|
||||
{
|
||||
int answ = 0;
|
||||
//using (DataLayerContext dbCtx = new DataLayerContext(_config))
|
||||
using (DataLayerContext dbCtx = new DataLayerContext())
|
||||
{
|
||||
// in primis se richiesto calcolo range periodo e svuoto...
|
||||
if (removeOld)
|
||||
{
|
||||
var firstRec = listRecords.OrderBy(x => x.Hour).FirstOrDefault();
|
||||
var lastRec = listRecords.OrderByDescending(x => x.Hour).FirstOrDefault();
|
||||
|
||||
if (firstRec != null && lastRec != null)
|
||||
{
|
||||
DateTime startDate = firstRec.Hour;
|
||||
DateTime endDate = lastRec.Hour;
|
||||
// uso direttamente ExecuteDelete
|
||||
await dbCtx
|
||||
.DbSetStatsDet
|
||||
.Where(x => x.Hour >= startDate && x.Hour < endDate)
|
||||
.ExecuteDeleteAsync();
|
||||
}
|
||||
}
|
||||
|
||||
// ora preparo inserimento massivo
|
||||
await dbCtx
|
||||
.DbSetStatsDet
|
||||
.AddRangeAsync(listRecords);
|
||||
|
||||
// salvo!
|
||||
answ = await dbCtx.SaveChangesAsync();
|
||||
|
||||
// libero memoria del changeTracker
|
||||
dbCtx.ChangeTracker.Clear();
|
||||
}
|
||||
return answ;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Elenco completo Tags
|
||||
/// </summary>
|
||||
|
||||
@@ -3,6 +3,7 @@ using EgwCoreLib.Lux.Data.DbModel.Cost;
|
||||
using EgwCoreLib.Lux.Data.DbModel.Items;
|
||||
using EgwCoreLib.Lux.Data.DbModel.Production;
|
||||
using EgwCoreLib.Lux.Data.DbModel.Sales;
|
||||
using EgwCoreLib.Lux.Data.DbModel.Stats;
|
||||
using EgwCoreLib.Lux.Data.DbModel.Stock;
|
||||
using EgwCoreLib.Lux.Data.DbModel.Task;
|
||||
using EgwCoreLib.Lux.Data.DbModel.Utils;
|
||||
@@ -77,8 +78,8 @@ namespace EgwCoreLib.Lux.Data
|
||||
public virtual DbSet<StockMovModel> DbSetStockMov { get; set; }
|
||||
public virtual DbSet<GenClassModel> DbSetGenClass { get; set; }
|
||||
public virtual DbSet<GenValueModel> DbSetGenVal { get; set; }
|
||||
|
||||
|
||||
public virtual DbSet<StatsDetail> DbSetStatsDet { get; set; }
|
||||
public virtual DbSet<StatsAggregated> DbSetStatsAggr { get; set; }
|
||||
|
||||
|
||||
partial void OnModelCreatingPartial(ModelBuilder modelBuilder);
|
||||
|
||||
@@ -1,8 +1,14 @@
|
||||
using EgwCoreLib.Lux.Core.Stats;
|
||||
using EgwCoreLib.Lux.Data.Controllers;
|
||||
using EgwCoreLib.Lux.Data.DbModel.Stats;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using NLog;
|
||||
using StackExchange.Redis;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace EgwCoreLib.Lux.Data.Services
|
||||
@@ -10,16 +16,30 @@ namespace EgwCoreLib.Lux.Data.Services
|
||||
/// <summary>
|
||||
/// Gestione servizio indice richieste
|
||||
/// </summary>
|
||||
public class CalcRuidService
|
||||
public class CalcRuidService : BaseServ
|
||||
{
|
||||
#region Public Constructors
|
||||
|
||||
public CalcRuidService(ConnectionMultiplexer redis, TimeSpan retention, string redisBaseKey)
|
||||
public CalcRuidService(IConfiguration configuration, IConnectionMultiplexer redisConn, string redisBaseKey, TimeSpan retention, TimeSpan archivePeriod) : base(configuration, redisConn)
|
||||
{
|
||||
_db = redis.GetDatabase();
|
||||
_retention = retention;
|
||||
_db = redisConn.GetDatabase();
|
||||
_base = redisBaseKey.TrimEnd(':');
|
||||
//_base = redisBaseKey.EndsWith(":") ? redisBaseKey : redisBaseKey + ":";
|
||||
_retention = retention;
|
||||
_archivePeriod = archivePeriod;
|
||||
// conf DB
|
||||
string connStr = BaseServ._config.GetConnectionString("Lux.All") ?? "";
|
||||
if (string.IsNullOrEmpty(connStr))
|
||||
{
|
||||
Log.Error("ConnString empty!");
|
||||
}
|
||||
else
|
||||
{
|
||||
//dbController = new Controllers.LuxController(_config);
|
||||
dbController = new LuxController();
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.AppendLine($"CalcRuidService | LuxController OK");
|
||||
Log.Info(sb.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
#endregion Public Constructors
|
||||
@@ -75,7 +95,6 @@ namespace EgwCoreLib.Lux.Data.Services
|
||||
return ruid;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Metodo di Cleanup periodico
|
||||
/// </summary>
|
||||
@@ -126,6 +145,57 @@ namespace EgwCoreLib.Lux.Data.Services
|
||||
await Task.WhenAll(tasks);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Metodo di Cleanup dato periodo limite prima del quale va eliminato l'elenco dei dati
|
||||
/// </summary>
|
||||
/// <param name="environment">Environment calcolo</param>
|
||||
/// <param name="tipo">Tipologia richiesta</param>
|
||||
/// <param name="timeLimit">Limite temporale dati da eliminare</param>
|
||||
/// <returns></returns>
|
||||
public async Task CleanupOldRequestsAsync(string environment, string tipo, TimeSpan timeLimit)
|
||||
{
|
||||
var cutoff = DateTimeOffset.UtcNow.Add(-timeLimit).ToUnixTimeMilliseconds();
|
||||
var setKey = GetSortedSetKey(environment, tipo);
|
||||
|
||||
var oldIds = await _db.SortedSetRangeByScoreAsync(setKey, stop: cutoff);
|
||||
if (oldIds.Length == 0) return;
|
||||
|
||||
var batch = _db.CreateBatch();
|
||||
var tasks = new List<Task>();
|
||||
|
||||
foreach (var id in oldIds)
|
||||
{
|
||||
var ruid = id.ToString();
|
||||
var hashKey = GetRequestKey(ruid);
|
||||
|
||||
var uid = await _db.HashGetAsync(hashKey, "UID");
|
||||
if (!uid.IsNull)
|
||||
{
|
||||
var uidKey = GetUidSetKey(uid);
|
||||
tasks.Add(batch.SetRemoveAsync(uidKey, ruid));
|
||||
|
||||
tasks.Add(batch.SetLengthAsync(uidKey).ContinueWith(t =>
|
||||
{
|
||||
if (t.Result == 0)
|
||||
_db.KeyDelete(uidKey);
|
||||
}));
|
||||
}
|
||||
|
||||
tasks.Add(batch.KeyDeleteAsync(hashKey));
|
||||
}
|
||||
|
||||
tasks.Add(batch.SortedSetRemoveRangeByScoreAsync(setKey, double.NegativeInfinity, cutoff));
|
||||
|
||||
tasks.Add(batch.SortedSetLengthAsync(setKey).ContinueWith(t =>
|
||||
{
|
||||
if (t.Result == 0)
|
||||
_db.KeyDelete(setKey);
|
||||
}));
|
||||
|
||||
batch.Execute();
|
||||
await Task.WhenAll(tasks);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Metodo di Aggiornamento richiesta esistente
|
||||
/// </summary>
|
||||
@@ -174,7 +244,6 @@ namespace EgwCoreLib.Lux.Data.Services
|
||||
await Task.WhenAll(t1, t2, t3);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Metodo Recupero combinazioni envir/tipo
|
||||
/// </summary>
|
||||
@@ -290,6 +359,8 @@ namespace EgwCoreLib.Lux.Data.Services
|
||||
|
||||
#region Private Fields
|
||||
|
||||
private static Logger Log = LogManager.GetCurrentClassLogger();
|
||||
private readonly TimeSpan _archivePeriod;
|
||||
private readonly string _base;
|
||||
private readonly IDatabase _db;
|
||||
private readonly TimeSpan _retention;
|
||||
@@ -297,6 +368,12 @@ namespace EgwCoreLib.Lux.Data.Services
|
||||
|
||||
#endregion Private Fields
|
||||
|
||||
#region Private Properties
|
||||
|
||||
private static LuxController dbController { get; set; } = null!;
|
||||
|
||||
#endregion Private Properties
|
||||
|
||||
#region Private Methods
|
||||
|
||||
/// <summary>
|
||||
|
||||
Reference in New Issue
Block a user