Preparazione metodi async x pagina ODL

This commit is contained in:
Samuele Locatelli
2026-05-28 12:11:53 +02:00
parent 92703f6bbd
commit 9df2a7853f
7 changed files with 87 additions and 114 deletions
+7 -18
View File
@@ -2198,25 +2198,14 @@ namespace MP.Data.Controllers
/// </summary>
/// <param name="idxPODL"></param>
/// <returns></returns>
public PODLModel PODL_getByOdl(int idxODL)
public async Task<PODLModel> PODL_getByOdlAsync(int idxODL)
{
PODLModel dbResult = new PODLModel();
using (var dbCtx = new MoonProContext(options))
{
try
{
dbResult = dbCtx
.DbSetPODL
.AsNoTracking()
.Where(x => x.IdxOdl == idxODL)
.FirstOrDefault();
}
catch (Exception exc)
{
Log.Error($"Eccezione durante PODL_getByOdl{Environment.NewLine}{exc}");
}
}
return dbResult;
using var dbCtx = new MoonProContext(options);
return await dbCtx
.DbSetPODL
.AsNoTracking()
.Where(x => x.IdxOdl == idxODL)
.FirstOrDefaultAsync() ?? new();
}
/// <summary>
+32 -13
View File
@@ -123,7 +123,7 @@ namespace MP.SPEC.Components
// ricarica...
await selRecord(null);
}
await ReloadData();
await ReloadDataAsync();
}
/// <summary>
@@ -151,18 +151,12 @@ namespace MP.SPEC.Components
// ricarica...
await selRecord(null);
}
await ReloadData();
await ReloadDataAsync();
}
protected int getPodl(int idxOdl)
{
int answ = 0;
var pOdlData = MDService.POdlGetByOdl(idxOdl);
if (pOdlData != null)
{
answ = pOdlData.IdxPromessa;
}
return answ;
return _podlLocalCache.TryGetValue(idxOdl, out var val) ? val : 0;
}
/// <summary>
@@ -227,13 +221,13 @@ namespace MP.SPEC.Components
protected override async Task OnParametersSetAsync()
{
await ReloadData();
await ReloadDataAsync();
}
protected async Task resetSel()
{
await selRecord(null);
await ReloadData();
await ReloadDataAsync();
}
protected async Task selBrowseRecord(ODLExpModel? currRec)
@@ -276,7 +270,7 @@ namespace MP.SPEC.Components
protected async Task UpdateData()
{
await selRecord(null);
await ReloadData();
await ReloadDataAsync();
}
#endregion Protected Methods
@@ -360,14 +354,39 @@ namespace MP.SPEC.Components
#region Private Methods
private async Task ReloadData()
private async Task ReloadDataAsync()
{
isLoading = true;
SearchRecords = await MDService.OdlListGetFilt(currFilter.IsActive, currFilter.SearchVal, currFilter.CodFase, currFilter.CodReparto, currFilter.IdxMacchina, currFilter.DtStart, currFilter.DtEnd);
await ReloadPOdlData();
totalCount = SearchRecords.Count;
ListRecords = SearchRecords.Skip(numRecord * (currPage - 1)).Take(numRecord).ToList();
isLoading = false;
}
private Dictionary<int, int> _podlLocalCache = new();
private async Task ReloadPOdlData()
{
_podlLocalCache.Clear();
if (SearchRecords != null)
{
// 1. Popolo la cache locale in parallelo sfruttando la velocità di FusionCache
var tasks = SearchRecords.Select(async odl =>
{
int podl = 0;
var pOdlData = await MDService.POdlGetByOdlAsync(odl.IdxOdl); // Tua nuova versione Async
if (pOdlData != null)
{
podl = pOdlData.IdxPromessa;
}
return (odl.IdxOdl, podl);
});
var infoSalvate = await Task.WhenAll(tasks);
// 2. Trasformazione dei risultati in un dizionario per l'accesso immediato (O(1)) nell'HTML
_podlLocalCache = infoSalvate.ToDictionary(x => x.IdxOdl, x => x.podl);
}
}
private async Task reloadStatsData(ODLExpModel? currRec)
{
+44 -79
View File
@@ -213,7 +213,7 @@ namespace MP.SPEC.Data
return await GetOrFetchAsync(
operationName: "AnagStatiCommAsync",
cacheKey: Utils.redisStatoCom,
expiration: TimeSpan.FromMinutes(redisLongTimeCache),
expiration: TimeSpan.FromSeconds(redisLongTimeCache),
fetchFunc: async () =>
await dbController.AnagStatiCommAsync() ?? new List<ListValuesModel>(),
tagList: [Utils.redisStatoCom]
@@ -229,7 +229,7 @@ namespace MP.SPEC.Data
return await GetOrFetchAsync(
operationName: "AnagTipoArtLvAsync",
cacheKey: Utils.redisTipoArt,
expiration: TimeSpan.FromMinutes(redisLongTimeCache),
expiration: TimeSpan.FromSeconds(redisLongTimeCache),
fetchFunc: async () => await dbController.AnagTipoArtLvAsync() ?? new List<ListValuesModel>(),
tagList: [Utils.redisTipoArt]
);
@@ -244,7 +244,7 @@ namespace MP.SPEC.Data
return await GetOrFetchAsync(
operationName: "ArticleWithDossierAsync",
cacheKey: Utils.redisArtByDossier,
expiration: TimeSpan.FromMinutes(redisLongTimeCache),
expiration: TimeSpan.FromSeconds(redisLongTimeCache),
fetchFunc: async () => await Task.FromResult(dbController.ArticleWithDossier()) ?? new List<string>(),
tagList: [Utils.redisArtByDossier]
);
@@ -302,7 +302,7 @@ namespace MP.SPEC.Data
return await GetOrFetchAsync(
operationName: "ArticoliGetSearchAsync",
cacheKey: redisKey,
expiration: TimeSpan.FromMinutes(redisLongTimeCache),
expiration: TimeSpan.FromSeconds(redisLongTimeCache),
fetchFunc: async () =>
await dbController.ArticoliGetSearchAsync(numRecord, tipoArt, azienda, searchVal) ?? new List<AnagArticoliModel>(),
tagList: [Utils.redisArtList, $"{Utils.redisArtList}:Search"]
@@ -422,7 +422,7 @@ namespace MP.SPEC.Data
return await GetOrFetchAsync(
operationName: "ConfigGetAllAsync",
cacheKey: Utils.redisConfKey,
expiration: TimeSpan.FromMinutes(redisLongTimeCache),
expiration: TimeSpan.FromSeconds(redisLongTimeCache),
fetchFunc: async () => await dbController.ConfigGetAllAsync() ?? new List<ConfigModel>(),
tagList: [Utils.redisConfKey]
);
@@ -676,7 +676,7 @@ namespace MP.SPEC.Data
return await GetOrFetchAsync(
operationName: "ElencoLinkAsync",
cacheKey: Utils.redisLinkMenu,
expiration: TimeSpan.FromMinutes(redisLongTimeCache),
expiration: TimeSpan.FromSeconds(redisLongTimeCache),
fetchFunc: async () => await dbController.ElencoLinkAsync() ?? new List<LinkMenuModel>(),
tagList: [Utils.redisLinkMenu]
);
@@ -1111,7 +1111,7 @@ namespace MP.SPEC.Data
return await GetOrFetchAsync(
operationName: "FluxLogParetoAsync",
cacheKey: redKey,
expiration: TimeSpan.FromMinutes(redisLongTimeCache),
expiration: TimeSpan.FromSeconds(redisLongTimeCache),
fetchFunc: async () => await dbController.FluxLogParetoAsync(idxMacchina, dtFrom, dtTo) ?? new List<ParetoFluxLogDTO>(),
tagList: [Utils.redisParetoFLKey]
);
@@ -1257,7 +1257,7 @@ namespace MP.SPEC.Data
return await GetOrFetchAsync(
operationName: "IstKitFiltAsync",
cacheKey: currKey,
expiration: TimeSpan.FromMinutes(redisLongTimeCache),
expiration: TimeSpan.FromSeconds(redisLongTimeCache),
fetchFunc: async () => await dbController.IstKitFiltAsync(keyKit, keyExtOrd) ?? new List<IstanzeKitModel>(),
tagList: [Utils.redisKitInst]
);
@@ -1513,7 +1513,7 @@ namespace MP.SPEC.Data
return await GetOrFetchAsync(
operationName: "MacchineWithFluxAsync",
cacheKey: currKey,
expiration: TimeSpan.FromMinutes(redisLongTimeCache),
expiration: TimeSpan.FromSeconds(redisLongTimeCache),
fetchFunc: async () => await dbController.MacchineWithFluxAsync(dtStart, dtEnd) ?? new List<string>(),
tagList: [Utils.redisMacByFlux]
);
@@ -1946,16 +1946,16 @@ namespace MP.SPEC.Data
/// </summary>
/// <param name="idxODL"></param>
/// <returns></returns>
public PODLModel POdlGetByOdl(int idxODL)
public async Task<PODLModel> POdlGetByOdlAsync(int idxODL)
{
PODLModel result = new PODLModel();
if (idxODL != 0)
{
using var activity = ActivitySource.StartActivity("POdlGetByOdl");
using var activity = ActivitySource.StartActivity("POdlGetByOdlAsync");
string source = "DB";
string currKey = $"{Utils.redisPOdlByOdl}:{idxODL}";
// cerco in redis dato valore sel idxMaccSel...
RedisValue rawData = redisDb.StringGet(currKey);
RedisValue rawData = await redisDb.StringGetAsync(currKey);
if (rawData.HasValue)
{
var rawResult = JsonConvert.DeserializeObject<PODLModel>($"{rawData}");
@@ -1967,10 +1967,10 @@ namespace MP.SPEC.Data
}
else
{
result = dbController.PODL_getByOdl(idxODL);
result = await dbController.PODL_getByOdlAsync(idxODL);
// serializzo e salvo...
rawData = JsonConvert.SerializeObject(result);
redisDb.StringSet(currKey, rawData, getRandTOut(redisLongTimeCache));
await redisDb.StringSetAsync(currKey, rawData, getRandTOut(redisLongTimeCache));
}
if (result == null)
{
@@ -1979,7 +1979,7 @@ namespace MP.SPEC.Data
activity?.SetTag("data.source", source);
activity?.SetTag("result.count", 1);
activity?.Stop();
Log.Trace($"POdlGetByOdl | Read from {source}: {activity?.Duration.TotalMilliseconds}ms");
Log.Trace($"POdlGetByOdlAsync | Read from {source}: {activity?.Duration.TotalMilliseconds}ms");
}
else
{
@@ -2054,47 +2054,6 @@ namespace MP.SPEC.Data
/// <param name="startDate">Data inizio</param>
/// <param name="endDate">Data fine</param>
/// <returns></returns>
public List<PODLExpModel> POdlListGetFilt(bool lanciato, string keyRichPart, string idxMacchina, string codGruppo, DateTime startDate, DateTime endDate)
{
using var activity = ActivitySource.StartActivity("POdlListGetFiltAsync");
List<PODLExpModel>? result = new List<PODLExpModel>();
string source = "DB";
string currKey = $"{Utils.redisPOdlList}:{codGruppo}:{idxMacchina}:{keyRichPart}:{lanciato}:{startDate:yyyyMMdd_HHmmss}:{endDate:yyyyMMdd_HHmmss}";
// cerco in redis dato valore sel idxMaccSel...
RedisValue rawData = redisDb.StringGet(currKey);
if (rawData.HasValue)
{
result = JsonConvert.DeserializeObject<List<PODLExpModel>>($"{rawData}");
source = "REDIS";
}
else
{
result = dbController.ListPODLFilt(lanciato, keyRichPart, idxMacchina, codGruppo, startDate, endDate);
// serializzo e salvo...
rawData = JsonConvert.SerializeObject(result);
redisDb.StringSet(currKey, rawData, TimeSpan.FromSeconds(redisShortTimeCache));
}
if (result == null)
{
result = new List<PODLExpModel>();
}
activity?.SetTag("data.source", source);
activity?.SetTag("result.count", result.Count);
activity?.Stop();
LogTrace($"POdlListGetFilt | Read from {source}: {activity?.Duration.TotalMilliseconds}ms");
return result;
}
/// <summary>
/// Elenco PODL (Async) non avviati filtrati x articolo, KeyRich (che contiene stato)
/// </summary>
/// <param name="lanciato">Solo lanciati (1) o ancora disponibili (0)</param>
/// <param name="keyRichPart">KeyRich (parziale) da cercare (es cod stato x yacht)</param>
/// <param name="idxMacchina">Macchina</param>
/// <param name="codGruppo">Gruppo</param>
/// <param name="startDate">Data inizio</param>
/// <param name="endDate">Data fine</param>
/// <returns></returns>
public async Task<List<PODLExpModel>> POdlListGetFiltAsync(bool lanciato, string keyRichPart, string idxMacchina, string codGruppo, DateTime startDate, DateTime endDate)
{
string currKey = $"{Utils.redisPOdlList}:{codGruppo}:{idxMacchina}:{keyRichPart}:{lanciato}:{startDate:yyyyMMdd_HHmmss}:{endDate:yyyyMMdd_HHmmss}";
@@ -2122,20 +2081,20 @@ namespace MP.SPEC.Data
string redisKey = $"{Utils.redisPOdlList}_kit:{codGruppo}:{idxMacchina}:{keyRichPart}:{lanciato}:{startDate:yyyyMMdd_HHmmss}:{endDate:yyyyMMdd_HHmmss}";
return await GetOrFetchAsync(
operationName: "POdlToKitListGetFiltAsync",
cacheKey: redisKey,
expiration: TimeSpan.FromSeconds(redisShortTimeCache * 5),
fetchFunc: async () =>
await dbController.ListPODL_KitFiltAsync(
lanciato,
keyRichPart,
idxMacchina,
codGruppo,
startDate,
endDate
) ?? new List<PODLExpModel>(),
tagList: [Utils.redisPOdlList, $"{Utils.redisPOdlList}_kit"]
);
operationName: "POdlToKitListGetFiltAsync",
cacheKey: redisKey,
expiration: TimeSpan.FromSeconds(redisShortTimeCache * 5),
fetchFunc: async () =>
await dbController.ListPODL_KitFiltAsync(
lanciato,
keyRichPart,
idxMacchina,
codGruppo,
startDate,
endDate
) ?? new List<PODLExpModel>(),
tagList: [Utils.redisPOdlList, $"{Utils.redisPOdlList}_kit"]
);
}
/// <summary>
@@ -2410,7 +2369,7 @@ namespace MP.SPEC.Data
var result = await GetOrFetchAsync(
operationName: "TemplateKitFiltAsync",
cacheKey: currKey,
expiration: TimeSpan.FromMinutes(redisLongTimeCache),
expiration: TimeSpan.FromSeconds(redisLongTimeCache),
fetchFunc: async () => await dbController.TemplateKitFiltAsync(codParent, codChild) ?? new List<TemplateKitModel>(),
tagList: [Utils.redisKitTempl]
);
@@ -2468,7 +2427,7 @@ namespace MP.SPEC.Data
result = await dbController.TksScoreAsync(KeyFilt, MaxResult);
// serializzo e salvo...
rawData = JsonConvert.SerializeObject(result);
await redisDb.StringSetAsync(currKey, rawData, TimeSpan.FromMinutes(redisLongTimeCache));
await redisDb.StringSetAsync(currKey, rawData, TimeSpan.FromSeconds(redisLongTimeCache));
}
if (result == null)
{
@@ -2599,7 +2558,7 @@ namespace MP.SPEC.Data
result = await dbController.WipKitFiltAsync(KeyFilt);
// serializzo e salvo...
rawData = JsonConvert.SerializeObject(result);
await redisDb.StringSetAsync(currKey, rawData, TimeSpan.FromMinutes(redisLongTimeCache));
await redisDb.StringSetAsync(currKey, rawData, TimeSpan.FromSeconds(redisLongTimeCache));
}
if (result == null)
{
@@ -2636,14 +2595,14 @@ namespace MP.SPEC.Data
#region Protected Methods
/// <summary>
/// Restituisce un timeout dai minuti richiesti + tempo random -15..+15 sec
/// Restituisce un timeout dal valore secondi richiesti + tempo random -10..+10 sec
/// </summary>
/// <param name="stdMinutes"></param>
/// <param name="durationSec"></param>
/// <returns></returns>
protected TimeSpan getRandTOut(double stdMinutes)
protected TimeSpan getRandTOut(double durationSec)
{
double rndValue = stdMinutes + (double)rand.Next(-15, 15) / 60;
return TimeSpan.FromMinutes(rndValue);
double rndValue = durationSec + (double)rand.Next(-5, 5);
return TimeSpan.FromSeconds(rndValue);
}
/// <summary>
@@ -2758,9 +2717,15 @@ namespace MP.SPEC.Data
/// </summary>
private IDatabase redisDb = null!;
/// <summary>
/// Durata cache breve standard (5 sec)
/// </summary>
private int redisLongTimeCache = 5;
private int redisShortTimeCache = 2;
/// <summary>
/// Durata cache long standard (5min)
/// </summary>
private int redisShortTimeCache = 300;
private bool traceEnabled = false;
+1 -1
View File
@@ -5,7 +5,7 @@
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<RootNamespace>MP.SPEC</RootNamespace>
<Version>8.16.2605.2811</Version>
<Version>8.16.2605.2812</Version>
<UserSecretsId>1800a78a-6ff1-40f9-b490-87fb8bfc1394</UserSecretsId>
<SatelliteResourceLanguages>en</SatelliteResourceLanguages>
</PropertyGroup>
+1 -1
View File
@@ -1,6 +1,6 @@
<body>
<i>Modulo MAPOSPEC </i>
<h4>Versione: 8.16.2605.2811</h4>
<h4>Versione: 8.16.2605.2812</h4>
<br /> Note di rilascio:
<ul>
<li>
+1 -1
View File
@@ -1 +1 @@
8.16.2605.2811
8.16.2605.2812
+1 -1
View File
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<item>
<version>8.16.2605.2811</version>
<version>8.16.2605.2812</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>