Update caching SPEC
This commit is contained in:
@@ -456,18 +456,18 @@ namespace MP.Data.Controllers
|
||||
/// <param name="azienda"></param>
|
||||
/// <param name="searchVal"></param>
|
||||
/// <returns></returns>
|
||||
public List<AnagArticoliModel> ArticoliGetSearch(int numRecord, string azienda = "*", string searchVal = "")
|
||||
public async Task<List<AnagArticoliModel>> ArticoliGetSearchAsync(int numRecord, string azienda = "*", string searchVal = "")
|
||||
{
|
||||
List<AnagArticoliModel> dbResult = new List<AnagArticoliModel>();
|
||||
using (var dbCtx = new MoonProContext(options))
|
||||
{
|
||||
dbResult = dbCtx
|
||||
.DbSetArticoli
|
||||
.AsNoTracking()
|
||||
.Where(x => (azienda == "*" || x.Azienda.ToUpper() == azienda.ToUpper()) && (string.IsNullOrEmpty(searchVal) || x.CodArticolo.Contains(searchVal) || x.DescArticolo.Contains(searchVal) || x.Disegno.Contains(searchVal)))
|
||||
.OrderBy(x => x.CodArticolo)
|
||||
.Take(numRecord)
|
||||
.ToList();
|
||||
dbResult = await dbCtx
|
||||
.DbSetArticoli
|
||||
.AsNoTracking()
|
||||
.Where(x => (azienda == "*" || x.Azienda.ToUpper() == azienda.ToUpper()) && (string.IsNullOrEmpty(searchVal) || x.CodArticolo.Contains(searchVal) || x.DescArticolo.Contains(searchVal) || x.Disegno.Contains(searchVal)))
|
||||
.OrderBy(x => x.CodArticolo)
|
||||
.Take(numRecord)
|
||||
.ToListAsync();
|
||||
}
|
||||
return dbResult;
|
||||
}
|
||||
@@ -1891,15 +1891,15 @@ namespace MP.Data.Controllers
|
||||
/// Recupero Odl CORRENTI
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public List<ODLModel> OdlGetCurrent()
|
||||
public async Task<List<ODLModel>> OdlGetCurrentAsync()
|
||||
{
|
||||
List<ODLModel> dbResult = new List<ODLModel>();
|
||||
using (var dbCtx = new MoonProContext(options))
|
||||
{
|
||||
dbResult = dbCtx
|
||||
.DbSetODL
|
||||
.Where(x => x.DataInizio != null && x.DataFine == null)
|
||||
.ToList();
|
||||
dbResult = await dbCtx
|
||||
.DbSetODL
|
||||
.Where(x => x.DataInizio != null && x.DataFine == null)
|
||||
.ToListAsync();
|
||||
}
|
||||
return dbResult;
|
||||
}
|
||||
|
||||
@@ -70,10 +70,7 @@ namespace MP.Data.Services
|
||||
}
|
||||
else
|
||||
{
|
||||
result = dbController.ArticoliGetSearch(numRecord, azienda, searchVal);
|
||||
#if false
|
||||
result = await Task.FromResult(dbController.ArticoliGetSearch(numRecord, azienda, searchVal));
|
||||
#endif
|
||||
result = await dbController.ArticoliGetSearchAsync(numRecord, azienda, searchVal);
|
||||
// serializzp e salvo...
|
||||
rawData = JsonConvert.SerializeObject(result);
|
||||
await _redisDb.StringSetAsync(currKey, rawData, LongCache);
|
||||
@@ -83,7 +80,7 @@ namespace MP.Data.Services
|
||||
result = new List<AnagArticoliModel>();
|
||||
}
|
||||
sw.Stop();
|
||||
Log.Debug($"ArticoliGetSearch | azienda: {azienda} | searchVal: {searchVal} | numRecord: {numRecord} | {source} | {sw.Elapsed.TotalMilliseconds}ms");
|
||||
Log.Debug($"ArticoliGetSearchAsync | azienda: {azienda} | searchVal: {searchVal} | numRecord: {numRecord} | {source} | {sw.Elapsed.TotalMilliseconds}ms");
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@@ -234,7 +234,7 @@ namespace MP.SPEC.Components
|
||||
ListStati = await MDService.AnagStatiComm();
|
||||
selAzienda = await MDService.ConfigTryGetAsync("AZIENDA");
|
||||
giacenzeConf = await MDService.ConfigTryGetAsync("SPEC_ShowGiacenze");
|
||||
ListArticoli = await MDService.ArticoliGetSearch(100000, selAzienda, "");
|
||||
ListArticoli = await MDService.ArticoliGetSearchAsync(100000, selAzienda, "");
|
||||
ListMacchine = MDService.MacchineGetFilt("*");
|
||||
await ReloadData(true);
|
||||
}
|
||||
|
||||
@@ -204,6 +204,9 @@ namespace MP.SPEC.Components
|
||||
ListRecords = null;
|
||||
isLoading = true;
|
||||
|
||||
var list = await MDService.OdlGetCurrentAsync();
|
||||
_odlCurrSet = list.ToHashSet();
|
||||
|
||||
var machines = await MDService.MacchineGetFiltAsync("*");
|
||||
|
||||
_machinesWithConf = machines
|
||||
@@ -244,7 +247,7 @@ namespace MP.SPEC.Components
|
||||
{
|
||||
ListRecords = null;
|
||||
isLoading = true;
|
||||
|
||||
await UpdateOdlList();
|
||||
// verifico filtro odl...
|
||||
if (actFilter.ShowKit)
|
||||
{
|
||||
@@ -259,8 +262,7 @@ namespace MP.SPEC.Components
|
||||
totalCount = SearchRecords.Count;
|
||||
}
|
||||
ListRecords = SearchRecords.Skip(numRecord * (currPage - 1)).Take(numRecord).ToList();
|
||||
await Task.Delay(1);
|
||||
await InvokeAsync(() => StateHasChanged());
|
||||
//await InvokeAsync(() => StateHasChanged());
|
||||
isLoading = false;
|
||||
}
|
||||
|
||||
@@ -356,6 +358,7 @@ namespace MP.SPEC.Components
|
||||
private static Logger Log = LogManager.GetCurrentClassLogger();
|
||||
private HashSet<string> _machinesWithArch = new();
|
||||
private HashSet<string> _machinesWithConf = new();
|
||||
private HashSet<string> _odlCurrSet = new();
|
||||
private string currRecipeArchPath = "";
|
||||
|
||||
/// <summary>
|
||||
@@ -567,18 +570,16 @@ namespace MP.SPEC.Components
|
||||
/// <returns></returns>
|
||||
private bool canStartOdl(string idxMacchina)
|
||||
{
|
||||
// controllo se lista scaduta...
|
||||
bool answ = false;
|
||||
DateTime adesso = DateTime.Now;
|
||||
if (adesso > odlCurrExp || odlCurrList == null || odlCurrList.Count == 0)
|
||||
{
|
||||
odlCurrList = MDService.OdlGetCurrent();
|
||||
odlCurrExp = adesso.AddSeconds(2);
|
||||
}
|
||||
answ = !odlCurrList.Contains(idxMacchina);
|
||||
return answ;
|
||||
return !_odlCurrSet.Contains(idxMacchina);
|
||||
}
|
||||
|
||||
private async Task UpdateOdlList()
|
||||
{
|
||||
var list = await MDService.OdlGetCurrentAsync();
|
||||
_odlCurrSet = list.ToHashSet();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Verifica se la idxMaccSel abbia associata un path x ricette (elenco)
|
||||
/// </summary>
|
||||
|
||||
+227
-44
@@ -1,5 +1,6 @@
|
||||
using EgwCoreLib.Utils;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.Caching.Memory;
|
||||
using MP.Core.Conf;
|
||||
using MP.Core.DTO;
|
||||
using MP.Core.Objects;
|
||||
@@ -20,10 +21,11 @@ namespace MP.SPEC.Data
|
||||
{
|
||||
#region Public Constructors
|
||||
|
||||
public MpDataService(IConfiguration configuration)
|
||||
public MpDataService(IConfiguration configuration, IMemoryCache memoryCache)
|
||||
{
|
||||
// fix oggetto configurazion
|
||||
// salvataggio oggetti
|
||||
_configuration = configuration;
|
||||
_memoryCache = memoryCache;
|
||||
// Verifica conf trace...
|
||||
traceEnabled = _configuration.GetValue<bool>("Otel:EnableTracing", false);
|
||||
Log.Info($"MpDataService | INIT | Trace enabled: {traceEnabled}");
|
||||
@@ -298,7 +300,18 @@ namespace MP.SPEC.Data
|
||||
LogTrace($"AnagKeyValGetAll Read from {source}: {activity?.Duration.TotalMilliseconds}ms");
|
||||
return result;
|
||||
}
|
||||
public async Task<List<ListValuesModel>> AnagStatiComm()
|
||||
{
|
||||
return await GetOrCreateCachedAsync(
|
||||
operationName: "AnagStatiComm",
|
||||
memKey: "ANAG_STATI_COMM_MEM",
|
||||
redisKey: Utils.redisStatoCom,
|
||||
memoryTtl: TimeSpan.FromMinutes(5),
|
||||
dbFactory: () => Task.FromResult(dbController.AnagStatiComm() ?? new List<ListValuesModel>())
|
||||
);
|
||||
}
|
||||
|
||||
#if false
|
||||
public async Task<List<ListValuesModel>> AnagStatiComm()
|
||||
{
|
||||
using var activity = ActivitySource.StartActivity("AnagStatiComm");
|
||||
@@ -327,7 +340,8 @@ namespace MP.SPEC.Data
|
||||
activity?.Stop();
|
||||
LogTrace($"AnagStatiComm Read from {source}: {activity?.Duration.TotalMilliseconds}ms");
|
||||
return result;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
public async Task<List<ListValuesModel>> AnagTipoArtLV()
|
||||
{
|
||||
@@ -417,6 +431,25 @@ namespace MP.SPEC.Data
|
||||
/// <param name="tipo"></param>
|
||||
/// <param name="azienda"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<List<AnagArticoliModel>> ArticoliGetByTipoAsync(string tipo, string azienda = "*")
|
||||
{
|
||||
string sKey = string.IsNullOrWhiteSpace(tipo) ? "ALL" : tipo.Trim();
|
||||
|
||||
string redisKey = $"{Utils.redisArtList}:{azienda}:Tipo:{sKey}";
|
||||
string memKey = $"MEM:{redisKey}";
|
||||
|
||||
return await GetOrCreateCachedAsync(
|
||||
operationName: "ArticoliGetByTipoAsync",
|
||||
memKey: memKey,
|
||||
redisKey: redisKey,
|
||||
// ✅ TTL lungo (dato abbastanza statico)
|
||||
memoryTtl: TimeSpan.FromMinutes(5),
|
||||
dbFactory: async () =>
|
||||
await dbController.ArticoliGetByTipoAsync(tipo, azienda)
|
||||
?? new List<AnagArticoliModel>()
|
||||
);
|
||||
}
|
||||
#if false
|
||||
public async Task<List<AnagArticoliModel>> ArticoliGetByTipoAsync(string tipo, string azienda = "*")
|
||||
{
|
||||
using var activity = ActivitySource.StartActivity("ArticoliGetByTipoAsync");
|
||||
@@ -447,7 +480,8 @@ namespace MP.SPEC.Data
|
||||
activity?.Stop();
|
||||
LogTrace($"ArticoliGetByTipoAsync | Read from {source}: {activity?.Duration.TotalMilliseconds}ms");
|
||||
return result;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/// <summary>
|
||||
/// Restitusice elenco articoli cercati
|
||||
@@ -455,38 +489,115 @@ namespace MP.SPEC.Data
|
||||
/// <param name="numRecord"></param>
|
||||
/// <param name="searchVal"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<List<AnagArticoliModel>> ArticoliGetSearch(int numRecord, string azienda, string searchVal)
|
||||
public async Task<List<AnagArticoliModel>> ArticoliGetSearchAsync(int numRecord, string azienda, string searchVal)
|
||||
{
|
||||
using var activity = ActivitySource.StartActivity("ArticoliGetSearch");
|
||||
List<AnagArticoliModel>? result = new List<AnagArticoliModel>();
|
||||
string source = "DB";
|
||||
string sKey = string.IsNullOrEmpty(searchVal) ? "***" : searchVal;
|
||||
string currKey = $"{Utils.redisArtList}:{azienda}:{sKey}";
|
||||
// cerco in redis dato valore sel idxMaccSel...
|
||||
RedisValue rawData = redisDb.StringGet(currKey);
|
||||
if (rawData.HasValue)
|
||||
string sKey = string.IsNullOrWhiteSpace(searchVal) ? "***" : searchVal.Trim();
|
||||
|
||||
string memKey = $"ART_SEARCH_MEM:{azienda}:{sKey}:{numRecord}";
|
||||
string redisKey = $"{Utils.redisArtList}:{azienda}:{sKey}:{numRecord}";
|
||||
|
||||
return await GetOrCreateCachedAsync(
|
||||
operationName: "ArticoliGetSearchAsync",
|
||||
memKey: memKey,
|
||||
redisKey: redisKey,
|
||||
memoryTtl: TimeSpan.FromMinutes(2),
|
||||
dbFactory: async () =>
|
||||
await dbController.ArticoliGetSearchAsync(numRecord, azienda, searchVal)
|
||||
?? new List<AnagArticoliModel>()
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Helper per gestione cache a 3 livelli: MEMORY, REDIS e DB con opzioni
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="operationName"></param>
|
||||
/// <param name="memKey"></param>
|
||||
/// <param name="redisKey"></param>
|
||||
/// <param name="memoryTtl"></param>
|
||||
/// <param name="dbFactory"></param>
|
||||
/// <param name="serialize"></param>
|
||||
/// <param name="deserialize"></param>
|
||||
/// <returns></returns>
|
||||
private async Task<T> GetOrCreateCachedAsync<T>(string operationName, string memKey, string redisKey, TimeSpan memoryTtl, Func<Task<T>> dbFactory, Func<T, string>? serialize = null, Func<string, T>? deserialize = null)
|
||||
{
|
||||
using var activity = ActivitySource.StartActivity(operationName);
|
||||
|
||||
string source = "NA";
|
||||
T result;
|
||||
|
||||
// ✅ default serializer (fallback)
|
||||
serialize ??= (obj) => JsonConvert.SerializeObject(obj);
|
||||
deserialize ??= (str) => JsonConvert.DeserializeObject<T>(str)!;
|
||||
|
||||
// ✅ 1. MEMORY
|
||||
if (_memoryCache.TryGetValue(memKey, out T cached))
|
||||
{
|
||||
result = JsonConvert.DeserializeObject<List<AnagArticoliModel>>($"{rawData}");
|
||||
source = "REDIS";
|
||||
result = cached;
|
||||
source = "MEMORY";
|
||||
}
|
||||
else
|
||||
{
|
||||
result = await Task.FromResult(dbController.ArticoliGetSearch(numRecord, azienda, searchVal));
|
||||
// serializzo e salvo...
|
||||
rawData = JsonConvert.SerializeObject(result);
|
||||
redisDb.StringSet(currKey, rawData, getRandTOut(redisLongTimeCache / 5));
|
||||
}
|
||||
if (result == null)
|
||||
{
|
||||
result = new List<AnagArticoliModel>();
|
||||
// ✅ 2. MISS → factory
|
||||
result = await _memoryCache.GetOrCreateAsync(memKey, async entry =>
|
||||
{
|
||||
entry.AbsoluteExpirationRelativeToNow = memoryTtl;
|
||||
|
||||
// 👉 REDIS
|
||||
try
|
||||
{
|
||||
var rawData = await redisDb.StringGetAsync(redisKey);
|
||||
|
||||
if (rawData.HasValue)
|
||||
{
|
||||
source = "REDIS";
|
||||
return deserialize(rawData!);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogTrace($"Redis error on {operationName}: {ex.Message}");
|
||||
}
|
||||
|
||||
// 👉 DB
|
||||
source = "DB";
|
||||
|
||||
var dbResult = await dbFactory();
|
||||
|
||||
var safeResult = dbResult == null ? default! : dbResult;
|
||||
|
||||
try
|
||||
{
|
||||
await redisDb.StringSetAsync(
|
||||
redisKey,
|
||||
serialize(safeResult),
|
||||
getRandTOut(redisLongTimeCache)
|
||||
);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogTrace($"Redis SET error on {operationName}: {ex.Message}");
|
||||
}
|
||||
|
||||
return safeResult;
|
||||
})!;
|
||||
}
|
||||
|
||||
// ✅ logging e tracing centralizzati
|
||||
activity?.SetTag("data.source", source);
|
||||
activity?.SetTag("result.count", result.Count);
|
||||
activity?.Stop();
|
||||
LogTrace($"ArticoliGetSearch | Read from {source}: {activity?.Duration.TotalMilliseconds}ms");
|
||||
|
||||
if (result is System.Collections.ICollection coll)
|
||||
activity?.SetTag("result.count", coll.Count);
|
||||
else
|
||||
activity?.SetTag("result.count", result != null ? 1 : 0);
|
||||
|
||||
LogTrace($"{operationName} | {source} | {activity?.Duration.TotalMilliseconds}ms");
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Aggiornamento record selezionato
|
||||
/// </summary>
|
||||
@@ -704,7 +815,7 @@ namespace MP.SPEC.Data
|
||||
activity?.SetTag("data.source", source);
|
||||
activity?.Stop();
|
||||
|
||||
LogTrace($"ConfigTryGetAsync | {keyName} | Read from {source}: {activity?.Duration.TotalMilliseconds}ms");
|
||||
LogTrace($"ConfigTryGetAsync | {keyName} | {source} | {activity?.Duration.TotalMilliseconds}ms");
|
||||
return value ?? "";
|
||||
}
|
||||
|
||||
@@ -1687,7 +1798,7 @@ namespace MP.SPEC.Data
|
||||
LogTrace($"MacchineGetFilt | Read from {source}: {activity?.Duration.TotalMilliseconds}ms");
|
||||
return result;
|
||||
}
|
||||
|
||||
private readonly IMemoryCache _memoryCache;
|
||||
/// <summary>
|
||||
/// Elenco di tutte le macchine filtrate x gruppo
|
||||
/// </summary>
|
||||
@@ -1695,32 +1806,51 @@ namespace MP.SPEC.Data
|
||||
/// <returns></returns>
|
||||
public async Task<List<MacchineModel>> MacchineGetFiltAsync(string codGruppo)
|
||||
{
|
||||
using var activity = ActivitySource.StartActivity("MacchineGetFilt");
|
||||
List<MacchineModel>? result = new List<MacchineModel>();
|
||||
using var activity = ActivitySource.StartActivity("MacchineGetFiltAsync");
|
||||
string source = "DB";
|
||||
|
||||
string keyGrp = codGruppo != "*" ? codGruppo : "ALL";
|
||||
string currKey = $"{Utils.redisMacList}:{keyGrp}";
|
||||
// cerco in redis dato valore sel idxMaccSel...
|
||||
RedisValue rawData = await redisDb.StringGetAsync(currKey);
|
||||
string memKey = $"MACCHINE_MEM:{keyGrp}";
|
||||
string redisKey = $"{Utils.redisMacList}:{keyGrp}";
|
||||
|
||||
// ✅ 1. MEMORY CACHE
|
||||
if (_memoryCache.TryGetValue(memKey, out List<MacchineModel> cached))
|
||||
{
|
||||
source = "MEMORY";
|
||||
activity?.SetTag("data.source", source);
|
||||
activity?.Stop();
|
||||
LogTrace($"MacchineGetFiltAsync | Read from {source}: {activity?.Duration.TotalMilliseconds}ms");
|
||||
return cached;
|
||||
}
|
||||
|
||||
List<MacchineModel> result;
|
||||
|
||||
// ✅ 2. REDIS
|
||||
var rawData = await redisDb.StringGetAsync(redisKey);
|
||||
|
||||
if (rawData.HasValue)
|
||||
{
|
||||
result = JsonConvert.DeserializeObject<List<MacchineModel>>($"{rawData}");
|
||||
result = JsonConvert.DeserializeObject<List<MacchineModel>>(rawData!) ?? new();
|
||||
source = "REDIS";
|
||||
}
|
||||
else
|
||||
{
|
||||
// ✅ 3. DB
|
||||
result = await dbController.MacchineGetFiltAsync(codGruppo);
|
||||
// serializzo e salvo...
|
||||
rawData = JsonConvert.SerializeObject(result);
|
||||
await redisDb.StringSetAsync(currKey, rawData, getRandTOut(redisLongTimeCache));
|
||||
}
|
||||
if (result == null)
|
||||
{
|
||||
result = new List<MacchineModel>();
|
||||
|
||||
await redisDb.StringSetAsync(
|
||||
redisKey,
|
||||
JsonConvert.SerializeObject(result),
|
||||
getRandTOut(redisLongTimeCache)
|
||||
);
|
||||
}
|
||||
|
||||
// ✅ salva in RAM (IMPORTANTISSIMO), TTL 1 minuto
|
||||
_memoryCache.Set(memKey, result, TimeSpan.FromMinutes(1));
|
||||
|
||||
activity?.SetTag("data.source", source);
|
||||
activity?.SetTag("result.count", 1);
|
||||
activity?.Stop();
|
||||
|
||||
LogTrace($"MacchineGetFiltAsync | Read from {source}: {activity?.Duration.TotalMilliseconds}ms");
|
||||
return result;
|
||||
}
|
||||
@@ -2040,6 +2170,32 @@ namespace MP.SPEC.Data
|
||||
/// </summary>
|
||||
/// <param name="idxMacchina"></param>
|
||||
/// <returns></returns>
|
||||
|
||||
public async Task<List<string>> OdlGetCurrentAsync()
|
||||
{
|
||||
string redisKey = Utils.redisOdlCurrByMac;
|
||||
string memKey = $"MEM:{redisKey}";
|
||||
|
||||
return await GetOrCreateCachedAsync(
|
||||
operationName: "OdlGetCurrentAsync",
|
||||
memKey: memKey,
|
||||
redisKey: redisKey,
|
||||
// ✅ TTL molto corto (come avevi: 3 secondi)
|
||||
memoryTtl: TimeSpan.FromSeconds(3),
|
||||
dbFactory: async () =>
|
||||
{
|
||||
var rawData = await dbController.OdlGetCurrentAsync();
|
||||
var dbResult = rawData
|
||||
.Select(x => x.IdxMacchina)
|
||||
.Distinct()
|
||||
.ToList();
|
||||
|
||||
return dbResult ?? new List<string>();
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
#if false
|
||||
public List<string> OdlGetCurrent()
|
||||
{
|
||||
using var activity = ActivitySource.StartActivity("OdlGetCurrent");
|
||||
@@ -2068,7 +2224,8 @@ namespace MP.SPEC.Data
|
||||
activity?.Stop();
|
||||
LogTrace($"OdlGetCurrent | Read from {source}: {activity?.Duration.TotalMilliseconds}ms");
|
||||
return dbResult;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/// <summary>
|
||||
/// elenco TUTTI gli ODL
|
||||
@@ -2479,6 +2636,31 @@ namespace MP.SPEC.Data
|
||||
/// <param name="startDate">Data inizio</param>
|
||||
/// <param name="endDate">Data fine</param>
|
||||
/// <returns></returns>
|
||||
public async Task<List<PODLExpModel>> POdlToKitListGetFiltAsync(bool lanciato, string keyRichPart, string idxMacchina, string codGruppo, DateTime startDate, DateTime endDate)
|
||||
{
|
||||
string currKey = $"{Utils.redisPOdlList}_kit:{codGruppo}:{idxMacchina}:{keyRichPart}:{lanciato}:{startDate:yyyyMMdd_HHmmss}:{endDate:yyyyMMdd_HHmmss}";
|
||||
|
||||
// ✅ stessa chiave per memoria (puoi anche prefissare)
|
||||
string memKey = $"MEM:{currKey}";
|
||||
|
||||
return await GetOrCreateCachedAsync(
|
||||
operationName: "POdlToKitListGetFiltAsync",
|
||||
memKey: memKey,
|
||||
redisKey: currKey,
|
||||
// ✅ TTL RAM breve (coerente con redisShortTimeCache)
|
||||
memoryTtl: TimeSpan.FromSeconds(redisShortTimeCache),
|
||||
dbFactory: async () =>
|
||||
await dbController.ListPODL_KitFiltAsync(
|
||||
lanciato,
|
||||
keyRichPart,
|
||||
idxMacchina,
|
||||
codGruppo,
|
||||
startDate,
|
||||
endDate
|
||||
) ?? new List<PODLExpModel>()
|
||||
);
|
||||
}
|
||||
#if false
|
||||
public async Task<List<PODLExpModel>> POdlToKitListGetFiltAsync(bool lanciato, string keyRichPart, string idxMacchina, string codGruppo, DateTime startDate, DateTime endDate)
|
||||
{
|
||||
using var activity = ActivitySource.StartActivity("POdlToKitListGetFiltAsync");
|
||||
@@ -2508,7 +2690,8 @@ namespace MP.SPEC.Data
|
||||
activity?.Stop();
|
||||
LogTrace($"POdlToKitListGetFiltAsync | Read from {source}: {activity?.Duration.TotalMilliseconds}ms");
|
||||
return result;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/// <summary>
|
||||
/// Chiamata salvataggio ricetta + refresh REDIS
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<RootNamespace>MP.SPEC</RootNamespace>
|
||||
<Version>8.16.2605.2617</Version>
|
||||
<Version>8.16.2605.2619</Version>
|
||||
<UserSecretsId>1800a78a-6ff1-40f9-b490-87fb8bfc1394</UserSecretsId>
|
||||
<SatelliteResourceLanguages>en</SatelliteResourceLanguages>
|
||||
</PropertyGroup>
|
||||
|
||||
@@ -335,7 +335,7 @@ namespace MP.SPEC.Pages
|
||||
private async Task ReloadData()
|
||||
{
|
||||
isLoading = true;
|
||||
SearchRecords = await MDService.ArticoliGetSearch(100000, selAzienda, SearchVal);
|
||||
SearchRecords = await MDService.ArticoliGetSearchAsync(100000, selAzienda, SearchVal);
|
||||
ListRecords = SearchRecords.Skip(numRecord * (currPage - 1)).Take(numRecord).ToList();
|
||||
isLoading = false;
|
||||
}
|
||||
|
||||
@@ -1,17 +1,14 @@
|
||||
#if false
|
||||
using Blazored.LocalStorage;
|
||||
#endif
|
||||
using EgwCoreLib.Razor;
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using Microsoft.JSInterop;
|
||||
using MP.Data.DbModels;
|
||||
using MP.SPEC.Components;
|
||||
using MP.Data.Services;
|
||||
using MP.SPEC.Data;
|
||||
using MP.SPEC.Services;
|
||||
using NLog;
|
||||
using System.Reflection.PortableExecutable;
|
||||
using EgwCoreLib.Razor;
|
||||
using Microsoft.AspNetCore.DataProtection;
|
||||
using MP.Data.Services;
|
||||
|
||||
namespace MP.SPEC.Pages
|
||||
{
|
||||
@@ -501,9 +498,8 @@ namespace MP.SPEC.Pages
|
||||
private async Task ReloadData()
|
||||
{
|
||||
isLoading = true;
|
||||
await Task.Delay(1);
|
||||
ListMacchine = MDService.MacchineGetFilt(selReparto);
|
||||
ListArticoli = await MDService.ArticoliGetSearch(100, currAzienda, artSearch);
|
||||
ListMacchine = await MDService.MacchineGetFiltAsync(selReparto);
|
||||
ListArticoli = await MDService.ArticoliGetSearchAsync(100, currAzienda, artSearch);
|
||||
if (ListGruppiFase != null)
|
||||
{
|
||||
var firstGroup = ListGruppiFase.Where(x => x.CodGruppo == selReparto).FirstOrDefault();
|
||||
|
||||
+6
-2
@@ -132,9 +132,13 @@ builder.Services.AddAuthorization(options =>
|
||||
builder.Services.AddRazorComponents()
|
||||
.AddInteractiveServerComponents();
|
||||
|
||||
// redis preliminare
|
||||
builder.Services.AddSingleton<IConnectionMultiplexer>(redisMultiplexer);
|
||||
builder.Services.AddRazorPages();
|
||||
|
||||
// memory + redis preliminare
|
||||
builder.Services.AddMemoryCache();
|
||||
builder.Services.AddSingleton<IConnectionMultiplexer>(redisMultiplexer);
|
||||
|
||||
// altri servizi
|
||||
builder.Services.AddSingleton<MpDataService>();
|
||||
builder.Services.AddSingleton<ListSelectDataSrv>();
|
||||
builder.Services.AddSingleton<IOApiService>();
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<body>
|
||||
<i>Modulo MAPOSPEC </i>
|
||||
<h4>Versione: 8.16.2605.2617</h4>
|
||||
<h4>Versione: 8.16.2605.2619</h4>
|
||||
<br /> Note di rilascio:
|
||||
<ul>
|
||||
<li>
|
||||
|
||||
@@ -1 +1 @@
|
||||
8.16.2605.2617
|
||||
8.16.2605.2619
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<item>
|
||||
<version>8.16.2605.2617</version>
|
||||
<version>8.16.2605.2619</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