Inizio update agents e modifiche x pagina ART con async vari e num records
This commit is contained in:
@@ -1,94 +1,22 @@
|
||||
# CI to Local Workflow Guide
|
||||
# MAPO-CORE Agent Instructions
|
||||
|
||||
This document describes how the GitLab CI pipeline in this repository translates to local commands that can be run on your machine. It also contains helper scripts and environment variables used by the CI.
|
||||
## Core Context
|
||||
- **Primary Goal**: Optimization and refactoring of the `MP-SPEC.sln` solution, focusing on migrating legacy Redis/DB caching to `FusionCache` (Memory + Redis + DB) in `MP.SPEC\Data\MpDataService.cs`.
|
||||
- **Language**: C# (primary), PowerShell (scripts).
|
||||
- **Documentation/Comments**: MUST be in **Italiano**.
|
||||
- **Code Style**: Maintain existing region organization (`#region Public Methods`, etc.).
|
||||
|
||||
## Environment Variables
|
||||
All variables listed below are interpolated in the CI templates. When running locally you can set them in a PowerShell profile or via `dotnet` arguments.
|
||||
## Development Workflow
|
||||
- **Build & Verification**:
|
||||
- Use a PowerShell script to build the solution to ensure continuous compilability.
|
||||
- Always verify that changes do not leave partial traces of old classes that break compilation.
|
||||
- **Refactoring Strategy (`MpDataService.cs`)**:
|
||||
- Use `GetOrFetchAsync<T>(string operationName, string cacheKey, Func<Task<T>> fetchFunc, TimeSpan expiration, params string[] tags)` as the standard for all data access.
|
||||
- Target methods currently using manual `redisDb.StringGetAsync` / `StringSetAsync` patterns.
|
||||
- **Testing**:
|
||||
- Check the codebase for existing testing patterns before proposing new ones.
|
||||
|
||||
| Variable | Description | Typical value |
|
||||
|----------|--------------|---------------|
|
||||
| `SOL_NAME` | Solution name to restore | **MP-STATS.sln** |
|
||||
| `PROJ_PATH` | Directory containing the main project | **MP.Stats** |
|
||||
| `APP_NAME` | Main project file name (without `.csproj`) | **MP.Stats** |
|
||||
| `NUGET_PATH` | NuGet credential file | **`C:\\Users\\samuele.steamw\AppData\Roaming\NuGet\Credentials.config`** |
|
||||
| `NEXUS_PATH` | Nexus host URL | **https://nexus.steamware.net** |
|
||||
| `DEST` | Artifacts output folder | **bin\publish** |
|
||||
| `VERS_MAIN`, `VERS_MAIN_APP`, `VERSSUB` | Version strings used in packaging | **1.0.0** /
|
||||
| `NEXUS_PASSWD` | Nexus password (secure via CI secret) | *Secret* |
|
||||
|
||||
## Build Pipeline (`buildjob`) – Local Equivalent
|
||||
|
||||
The CI first restores NuGet packages and then builds the solution for the selected `APP_NAME`.
|
||||
|
||||
```powershell
|
||||
# 1. Restore
|
||||
#$env:SOL_NAME.sln is resolved by the .nuget-fix script
|
||||
# In PowerShell: dotnet restore "MP-STATS.sln"
|
||||
|
||||
# 2. Build
|
||||
# $env:APP_NAME/$env:APP_NAME.csproj points to the project file
|
||||
# In PowerShell: dotnet build "MP.Stats/MP.Stats.csproj"
|
||||
```
|
||||
|
||||
### Helper: `.nuget-fix`
|
||||
The `.nuget-fix` PowerShell script removes any stale NuGet sources that conflict with the Nexus proxy and re‑adds the latest proxy source with credentials. Ensure this script runs *before* `dotnet restore`.
|
||||
|
||||
## Deploy Pipeline (`deployjob`) – Local Equivalent
|
||||
|
||||
Deployment in CI rebuilds the project, publishes it, hashes the output, and uploads it to Nexus. The same steps can be executed locally.
|
||||
|
||||
```powershell
|
||||
# 1. Rebuild (same as Build)
|
||||
# dotnet build "MP.Stats/MP.Stats.csproj"
|
||||
|
||||
# 2. Publish to a local folder
|
||||
# The `dotnet publish` command mimics the CI publish step. The `-c Release` ensures a Release build.
|
||||
# In PowerShell:
|
||||
# dotnet publish "MP.Stats/MP.Stats.csproj" -c Release -o publish
|
||||
|
||||
# 3. Create hashes (MD5 & SHA1)
|
||||
# The .hashBuild template generates .md5 and .sha1 files alongside the ZIP. A simple replacement can be
|
||||
# 1. Zip the folder: `Compress-Archive -Path publish -DestinationPath $(APP_NAME).zip`
|
||||
# 2. Generate hashes:
|
||||
# (Get-FileHash -Algorithm MD5 "$(APP_NAME).zip").Hash | Out-File "$(APP_NAME).md5"
|
||||
# (Get-FileHash -Algorithm SHA1 "$(APP_NAME).zip").Hash | Out-File "$(APP_NAME).sha1"
|
||||
|
||||
# 4. Upload to Nexus (requires `curl`)
|
||||
# Example curl command (CI uses `nexus-curl` script):
|
||||
# $curl -u $(NUGET_USER):$(NEXUS_PASSWD) "$(NEXUS_PATH)/repository/$(APP_NAME)" -T "$(APP_NAME).zip"
|
||||
```
|
||||
|
||||
## Installer & Release
|
||||
The **installer** template copies the published artifacts to a staging folder and optionally creates installers. The **release** template bumps version numbers, updates the `nuspec`, generates a changelog, and pushes the packages to Nexus.
|
||||
|
||||
Generally these steps are CI‑only, but you can repeat the same `dotnet pack` / `nuget push` commands locally if needed.
|
||||
|
||||
## Common Issues & Fixes
|
||||
|
||||
* _NuGet authentication errors_: Run `.nuget-fix` to reset the sources.
|
||||
* _Missing SDK_: Verify `dotnet --list-sdks` includes at least one SDK.
|
||||
* _Hashes not matching_: Ensure the ZIP file is identical to the one CI produced (same path, no hidden files).
|
||||
|
||||
## Quick Start
|
||||
```powershell
|
||||
# Restore
|
||||
.\.nuget-fix
|
||||
|
||||
# Build
|
||||
|
||||
dotnet restore "MP-STATS.sln"
|
||||
dotnet build "MP.Stats/MP.Stats.csproj"
|
||||
|
||||
# Publish & run
|
||||
|
||||
dotnet publish "MP.Stats/MP.Stats.csproj" -c Release -o publish
|
||||
dotnet run --project "MP.Stats/MP.Stats.csproj"
|
||||
|
||||
# For hot‑reload during development
|
||||
|
||||
dotnet watch run --project "MP.Stats/MP.Stats.csproj"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
Feel free to adjust paths or environment variable names if your local setup differs.
|
||||
## Architecture Notes
|
||||
- **Multi-Layer Caching**: The system is transitioning from a dual-layer (Redis + DB) to a triple-layer approach via `IFusionCache`.
|
||||
- **Service Responsibility**: `MpDataService` is the central hub for data access, interacting with `MpSpecController` (EFCore) and `MpMongoController` (MongoDB).
|
||||
- **Key Management**: Cache keys are heavily managed via `Utils.redis...` constants.
|
||||
|
||||
BIN
Binary file not shown.
@@ -5,7 +5,7 @@
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<RootNamespace>MP.SPEC</RootNamespace>
|
||||
<Version>8.16.2605.2712</Version>
|
||||
<Version>8.16.2605.2714</Version>
|
||||
<UserSecretsId>1800a78a-6ff1-40f9-b490-87fb8bfc1394</UserSecretsId>
|
||||
<SatelliteResourceLanguages>en</SatelliteResourceLanguages>
|
||||
</PropertyGroup>
|
||||
|
||||
@@ -19,10 +19,10 @@
|
||||
<div class="px-0 align-content-center">
|
||||
<div class="input-group">
|
||||
<span class="input-group-text"><i class="fa fa-search"></i></span>
|
||||
<input type="text" class="form-control" placeholder="Cerca (3+ char)" aria-label="Ricerca" title="Ricerca (3+ char)" @bind="@SearchVal">
|
||||
<input type="text" class="form-control form-control-sm" placeholder="Cerca (3+ char)" aria-label="Ricerca" title="Ricerca (3+ char)" @bind="@SearchVal">
|
||||
<button class="btn @searchCss" @onclick="() => resetSearch()"><i class="fa fa-ban"></i></button>
|
||||
<label class="input-group-text" for="maxRecord" title="Selezionare l'azienda da visualizzare"><i class="fa-solid fa-industry"></i></label>
|
||||
<select @bind="@selAzienda" class="form-select" title="Selezionare l'azienda da visualizzare">
|
||||
<select @bind="@selAzienda" class="form-select form-select-sm" title="Selezionare l'azienda da visualizzare">
|
||||
@if (ListAziende != null)
|
||||
{
|
||||
foreach (var item in ListAziende)
|
||||
@@ -31,6 +31,8 @@
|
||||
}
|
||||
}
|
||||
</select>
|
||||
<span class="input-group-text"><i class="fa fa-database"></i></span>
|
||||
<input type="number" class="form-control form-control-sm" aria-label="Num record" title="NUm massimo record da recuperare" @bind="@maxNumRecord" width="5">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<body>
|
||||
<i>Modulo MAPOSPEC </i>
|
||||
<h4>Versione: 8.16.2605.2712</h4>
|
||||
<h4>Versione: 8.16.2605.2714</h4>
|
||||
<br /> Note di rilascio:
|
||||
<ul>
|
||||
<li>
|
||||
|
||||
@@ -1 +1 @@
|
||||
8.16.2605.2712
|
||||
8.16.2605.2714
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<item>
|
||||
<version>8.16.2605.2712</version>
|
||||
<version>8.16.2605.2714</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,49 @@
|
||||
# Piano di Refactoring: Migrazione a FusionCache in `MpDataService.cs`
|
||||
|
||||
## Obiettivo
|
||||
Migrare la logica di caching manuale (Redis + DB) verso l'utilizzo di `IFusionCache` per implementare un approccio multi-layer (Memory + Redis + DB), standardizzando l'accesso ai dati.
|
||||
|
||||
## Analisi dello stato attuale
|
||||
- **Classe target**: `MP.SPEC\Data\MpDataService.cs`
|
||||
- **Pattern attuale**: Molti metodi utilizzano manualmente `redisDb.StringGetAsync` e `redisDb.StringSetAsync` con serializzazione JSON manuale.
|
||||
- **Metodo Standard**: `GetOrFetchAsync<T>(string operationName, string cacheKey, Func<Task<T>> fetchFunc, TimeSpan expiration, params string[] tags)`.
|
||||
|
||||
## Strategia di Migrazione
|
||||
|
||||
### 1. Identificazione Metodi Target
|
||||
Andrò a mappare tutti i metodi in `MpDataService.cs` che:
|
||||
- Utilizzano `redisDb` direttamente per la lettura/scrittura.
|
||||
- Gestiscono manualmente la serializzazione/deserializzazione con `JsonConvert`.
|
||||
- Gestiscono manualmente il fallback dal Redis al DB.
|
||||
|
||||
### 2. Classificazione Metodi
|
||||
I metodi verranno suddivisi in:
|
||||
- **Lettura (Cache-aside)**: Metodi che recuperano dati. Questi saranno i candidati principali per `GetOrFetchAsync`.
|
||||
- **Scrittura/Invalidazione**: Metodi che aggiornano il DB e devono invalidare la cache (es. `AnagGruppiUpsert`, `ArticoliUpdateRecord`). Questi dovranno utilizzare `_cache.RemoveByTagAsync` o `_cache.RemoveAsync`.
|
||||
|
||||
### 3. Piano di Implementazione (Step-by-Step)
|
||||
|
||||
#### Fase 1: Analisi e Mapping
|
||||
- [ ] Identificare ogni occorrenza di `redisDb.StringGet` / `StringGetAsync` in `MpDataService.cs`.
|
||||
- [ ] Verificare se la chiave di cache utilizzata è gestita tramite `Utils.redis...`.
|
||||
|
||||
#### Fase 2: Refactoring Metodi di Lettura
|
||||
Per ogni metodo di lettura individuato:
|
||||
- [ ] Sostituire la logica `if (rawData.HasValue) { ... } else { ... }` con la chiamata a `GetOrFetchAsync`.
|
||||
- [ ] Assicurarsi che il `fetchFunc` esegua la chiamata al `dbController`.
|
||||
- [ ] Configurare correttamente il `TimeSpan expiration` (usando le costanti esistenti come `redisLongTimeCache` o `redisShortTimeCache`).
|
||||
- [ ] Aggiungere i tag appropriati per permettere l'invalidazione granulare.
|
||||
|
||||
#### Fase 3: Refactoring Metodi di Scrittura e Invalidazione
|
||||
- [ ] Sostituire le chiamate manuali a `ExecFlushRedisPattern` o `redisDb.KeyDelete` con i metodi di invalidazione di `IFusionCache`.
|
||||
- [ ] Utilizzare i tag per invalidare gruppi di dati correlati invece di pattern Redis generici quando possibile.
|
||||
|
||||
#### Fase 4: Verifica
|
||||
- [ ] Verificare la compilazione della soluzione tramite script PowerShell.
|
||||
- [ ] Controllare che i log (NLog) continuino a riflettere correttamente le operazioni.
|
||||
|
||||
## Rischi e Mitigazioni
|
||||
- **Rischio**: Discrepanza nelle chiavi di cache tra vecchio e nuovo sistema.
|
||||
- *Mitigazione*: Utilizzare rigorosamente le costanti in `Utils.redis...` per garantire che le chiavi siano identiche o gestite dal nuovo sistema.
|
||||
- **Rischio**: Errori di serializzazione.
|
||||
- *Mitigazione*: `FusionCache` gestisce la serializzazione, ma è necessario assicurarsi che i tipi di ritorno siano compatibili con le aspettative dei chiamanti.
|
||||
@@ -1,63 +0,0 @@
|
||||
# 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