Continuo refactor con cache Fusion
This commit is contained in:
@@ -164,9 +164,9 @@ namespace MP.Data.Controllers
|
||||
/// Elenco Gruppi tipo Azienda
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public List<AnagGruppiModel> AnagGruppiAziende()
|
||||
public Task<List<AnagGruppiModel>> AnagGruppiAziendeAsync()
|
||||
{
|
||||
return AnagGruppiGetTipo("AZIENDA");
|
||||
return AnagGruppiGetTipoAsync("AZIENDA");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -241,6 +241,26 @@ namespace MP.Data.Controllers
|
||||
return dbResult;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gruppi x tipo modalità Async
|
||||
/// </summary>
|
||||
/// <param name="tipoGruppo"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<List<AnagGruppiModel>> AnagGruppiGetTipoAsync(string tipoGruppo)
|
||||
{
|
||||
List<AnagGruppiModel> dbResult = new List<AnagGruppiModel>();
|
||||
using (var dbCtx = new MoonProContext(options))
|
||||
{
|
||||
dbResult = await dbCtx
|
||||
.DbSetAnagGruppi
|
||||
.Where(x => x.TipoGruppo == tipoGruppo)
|
||||
.AsNoTracking()
|
||||
.OrderBy(x => x.CodGruppo)
|
||||
.ToListAsync();
|
||||
}
|
||||
return dbResult;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Elenco Gruppi tipo REPARTO (x associazione Macchine-Operatori)
|
||||
/// </summary>
|
||||
|
||||
@@ -1,12 +1,9 @@
|
||||
using Amazon.Runtime.Internal.Endpoints.StandardLibrary;
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using Microsoft.AspNetCore.Components.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc.RazorPages;
|
||||
using Microsoft.JSInterop;
|
||||
using MP.AppAuth.Services;
|
||||
using MP.SPEC.Data;
|
||||
using MP.SPEC.Extensions;
|
||||
using System;
|
||||
|
||||
namespace MP.SPEC.Components
|
||||
{
|
||||
@@ -56,6 +53,7 @@ namespace MP.SPEC.Components
|
||||
protected async Task FlushCache()
|
||||
{
|
||||
await MDService.FlushRedisCache();
|
||||
await MDService.FlushCacheAsync();
|
||||
await ForceReload();
|
||||
// rimando a pagina corrente
|
||||
NavManager.NavigateTo(NavManager.Uri, true);
|
||||
|
||||
@@ -306,7 +306,7 @@ namespace MP.SPEC.Data
|
||||
return await GetOrFetchAsync(
|
||||
operationName: "AnagStatiCommAsync",
|
||||
cacheKey: Utils.redisStatoCom,
|
||||
expiration: TimeSpan.FromMinutes(5),
|
||||
expiration: TimeSpan.FromMinutes(redisLongTimeCache),
|
||||
fetchFunc: async () =>
|
||||
await dbController.AnagStatiCommAsync() ?? new List<ListValuesModel>()
|
||||
);
|
||||
@@ -633,6 +633,7 @@ namespace MP.SPEC.Data
|
||||
{
|
||||
bool fatto = false;
|
||||
await _cache.ClearAsync();
|
||||
_configData.Clear();
|
||||
fatto = true;
|
||||
return fatto;
|
||||
}
|
||||
@@ -648,6 +649,7 @@ namespace MP.SPEC.Data
|
||||
{
|
||||
await _cache.RemoveByTagAsync(item);
|
||||
}
|
||||
_configData.Clear();
|
||||
fatto = true;
|
||||
return fatto;
|
||||
}
|
||||
@@ -659,6 +661,7 @@ namespace MP.SPEC.Data
|
||||
{
|
||||
bool fatto = false;
|
||||
await _cache.RemoveByTagAsync(tag);
|
||||
_configData.Clear();
|
||||
fatto = true;
|
||||
return fatto;
|
||||
}
|
||||
@@ -1198,14 +1201,14 @@ namespace MP.SPEC.Data
|
||||
/// Restitusice elenco aziende
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public List<AnagGruppiModel> ElencoAziende()
|
||||
public async Task<List<AnagGruppiModel>> ElencoAziendeAsync()
|
||||
{
|
||||
using var activity = ActivitySource.StartActivity("ElencoAziende");
|
||||
using var activity = ActivitySource.StartActivity("ElencoAziendeAsync");
|
||||
string source = "DB";
|
||||
var listAz = dbController.AnagGruppiAziende();
|
||||
var listAz = await dbController.AnagGruppiAziendeAsync();
|
||||
activity?.SetTag("data.source", source);
|
||||
activity?.Stop();
|
||||
LogTrace($"ElencoAziende | Read from {source}: {activity?.Duration.TotalMilliseconds}ms");
|
||||
LogTrace($"ElencoAziendeAsync | Read from {source}: {activity?.Duration.TotalMilliseconds}ms");
|
||||
return listAz;
|
||||
}
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<RootNamespace>MP.SPEC</RootNamespace>
|
||||
<Version>8.16.2605.2708</Version>
|
||||
<Version>8.16.2605.2709</Version>
|
||||
<UserSecretsId>1800a78a-6ff1-40f9-b490-87fb8bfc1394</UserSecretsId>
|
||||
<SatelliteResourceLanguages>en</SatelliteResourceLanguages>
|
||||
</PropertyGroup>
|
||||
|
||||
@@ -176,7 +176,7 @@ namespace MP.SPEC.Pages
|
||||
{
|
||||
selAzienda = "*";
|
||||
}
|
||||
ListAziende = MDService.ElencoAziende();
|
||||
ListAziende = await MDService.ElencoAziendeAsync();
|
||||
ListTipoArt = await MDService.AnagTipoArtLV();
|
||||
}
|
||||
|
||||
|
||||
@@ -129,7 +129,7 @@ namespace MP.SPEC.Pages
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
await getReparto();
|
||||
ListAziende = MDService.ElencoAziende();
|
||||
ListAziende = await MDService.ElencoAziendeAsync();
|
||||
var allGruppiData = MDService.ElencoGruppiFase();
|
||||
if (allGruppiData != null)
|
||||
{
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<body>
|
||||
<i>Modulo MAPOSPEC </i>
|
||||
<h4>Versione: 8.16.2605.2708</h4>
|
||||
<h4>Versione: 8.16.2605.2709</h4>
|
||||
<br /> Note di rilascio:
|
||||
<ul>
|
||||
<li>
|
||||
|
||||
@@ -1 +1 @@
|
||||
8.16.2605.2708
|
||||
8.16.2605.2709
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<item>
|
||||
<version>8.16.2605.2708</version>
|
||||
<version>8.16.2605.2709</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>
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
# Refactoring Plan: MpDataService Cache Layer Upgrade
|
||||
|
||||
## Objective
|
||||
Migrate all data access methods in `MpDataService.cs` to use the unified multi-level cache stack (IMemoryCache via `IFusionCache` + Redis + DB) using the `GetOrFetchAsync` pattern.
|
||||
|
||||
## Current State
|
||||
- Some methods use a manual "Redis + DB" approach (checking `redisDb.StringGet`, deserializing, and then `StringSet` on miss).
|
||||
- Some methods use the new `GetOrFetchAsync` pattern (Memory + Redis + DB).
|
||||
- `GetOrFetchAsync` leverages `IFusionCache`, which handles the multi-level complexity and provides better resiliency (fail-safe).
|
||||
|
||||
## Target Pattern: `GetOrFetchAsync`
|
||||
All read methods should be refactored to:
|
||||
1. Use `GetOrFetchAsync` to abstract cache management.
|
||||
2. Define a `cacheKey` (typically matching the existing Redis key).
|
||||
3. Provide an `expiration` (TimeSpan).
|
||||
4. Provide a `fetchFunc` that calls the `dbController` method.
|
||||
|
||||
## Proposed Work Items
|
||||
|
||||
### 1. Analysis & Categorization
|
||||
Identify all methods in `MpDataService.cs` that currently implement manual Redis caching.
|
||||
|
||||
**Candidates for Refactoring (Redis + DB -> Multi-level):**
|
||||
- `AnagEventiGeneral` (Lines 166-195)
|
||||
- `AnagEventiGetByMacch` (Lines 201-230)
|
||||
- `AnagKeyValGetAll` (Lines 273-302)
|
||||
- `AnagTipoArtLV` (Lines 347-375)
|
||||
- `ArticleWithDossier` (Lines 381-410)
|
||||
- `ConfigGetAll` (Lines 907-936)
|
||||
- `ConfigGetAllAsync` (Lines 943-970)
|
||||
- `DbDedupStats` (Lines 1046-1067)
|
||||
- `ElencoGruppiFase` (Lines 1216-1249)
|
||||
- `ElencoRepartiDTO` (Lines 1267-1303)
|
||||
- `FluxLogGetLastFilt` (Lines 1569-1605)
|
||||
- `FluxLogPareto` (Lines 1609-1640)
|
||||
- `MacchineRecipeArchive` (Lines 2100-2128)
|
||||
- `MacchineRecipeConf` (Lines 2131-2163)
|
||||
- `MacchineWithFlux` (Lines 2171-2200)
|
||||
- `OdlByBatch` (Lines 2308-2336)
|
||||
- `OdlListAll` (Lines 2490-2499) - *Currently no cache, needs addition?*
|
||||
- `OdlListGetFilt` (Lines 2513-2542)
|
||||
- `OperatoriGetFilt` (Lines 2549-2577)
|
||||
- `ParametriGetFilt` (Lines 2585-2614)
|
||||
- `POdlGetByKey` (Lines 2658-2697)
|
||||
- `POdlGetByOdl` (Lines 2705-2744)
|
||||
- `POdlListByKitParent` (Lines 2770-2800)
|
||||
- `POdlListGetFilt` (Lines 2812-2841)
|
||||
- `TksScore` (Lines 3343-3372)
|
||||
- `VocabolarioGetAll` (Lines 3445-3477)
|
||||
- `WipKitFilt` (Lines 3543-3570)
|
||||
|
||||
### 2. Implementation Steps
|
||||
For each candidate method:
|
||||
1. **Convert to Async**: If the method is synchronous (e.g., `AnagEventiGeneral`), convert it to `Task<T>` to match the `GetOrFetchAsync` signature.
|
||||
2. **Map Keys**: Ensure the `cacheKey` passed to `GetOrFetchAsync` is identical to the old Redis key to prevent cache fragmentation.
|
||||
3. **Set Expiration**: Use appropriate `TimeSpan` (e.g., `redisLongTimeCache` or `redisShortTimeCache` converted to `TimeSpan`).
|
||||
4. **Cleanup**: Remove manual `JsonConvert` logic and `redisDb.StringGet/Set` calls.
|
||||
5. **Verify Tracing**: Ensure `ActivitySource` and `LogTrace` are preserved or integrated within the `GetOrFetchAsync` wrapper.
|
||||
|
||||
### 3. Validation
|
||||
- Ensure all refactored methods are still called correctly by consumers.
|
||||
- Verify that `GetOrFetchAsync` correctly hits Memory first, then Redis, then DB.
|
||||
- Confirm that `LogTrace` still reports the correct source (MEMORY, REDIS, or DB).
|
||||
Reference in New Issue
Block a user