diff --git a/MP.Data/Services/BaseServ.cs b/MP.Data/Services/BaseServ.cs
index 0a6dbf7e..df5344c6 100644
--- a/MP.Data/Services/BaseServ.cs
+++ b/MP.Data/Services/BaseServ.cs
@@ -10,7 +10,6 @@ using System.Linq;
using System.Runtime.CompilerServices;
using System.Threading.Tasks;
using ZiggyCreatures.Caching.Fusion;
-using static Org.BouncyCastle.Asn1.Cmp.Challenge;
namespace MP.Data.Services
{
@@ -54,6 +53,35 @@ namespace MP.Data.Services
GC.SuppressFinalize(this);
}
+ ///
+ /// Cancellazione FusionCache (totale) - wrapper public
+ ///
+ ///
+ public Task ForceFlushFusionCacheAsync()
+ {
+ return FlushFusionCacheAsync();
+ }
+
+ ///
+ /// Cancellazione Fusion Cache x tag (wrapper)
+ ///
+ ///
+ ///
+ public Task ForceFlushFusionCacheAsync(string tag)
+ {
+ return FlushFusionCacheAsync(tag);
+ }
+
+ ///
+ /// Cancellazione Fusion Cache x list tags (wrapper)
+ ///
+ ///
+ ///
+ public Task ForceFlushFusionCacheAsync(List listTags)
+ {
+ return FlushFusionCacheAsync(listTags);
+ }
+
///
/// Recupero info IOB x TAB (da info registrate IOB-WIN--> MP-IO)
///
@@ -525,5 +553,50 @@ namespace MP.Data.Services
private double slowLogThresh = 0;
#endregion Private Fields
+
+ #region Private Methods
+
+ ///
+ /// Cancellazione FusionCache (totale)
+ ///
+ ///
+ private async Task FlushFusionCacheAsync()
+ {
+ await _cache.ClearAsync(allowFailSafe: false);
+ return true;
+ }
+
+ ///
+ /// Cancellazione FusionCache dato singolo tag
+ ///
+ ///
+ ///
+ private async Task FlushFusionCacheAsync(string tag)
+ {
+ if (string.IsNullOrWhiteSpace(tag)) return false;
+
+ await _cache.RemoveByTagAsync(tag);
+ return true;
+ }
+
+ ///
+ /// Cancellazione FusionCache dato elenco tags
+ ///
+ ///
+ ///
+ private async Task FlushFusionCacheAsync(List listTags)
+ {
+ if (listTags == null || listTags.Count == 0) return false;
+
+ // Generiamo i Task di rimozione ed eseguiamoli in parallelo su Redis/L1
+ var tasks = listTags
+ .Where(tag => !string.IsNullOrWhiteSpace(tag))
+ .Select(tag => _cache.RemoveByTagAsync(tag).AsTask());
+
+ await Task.WhenAll(tasks);
+ return true;
+ }
+
+ #endregion Private Methods
}
}
\ No newline at end of file
diff --git a/MP.Data/Services/IOC/IIocService.cs b/MP.Data/Services/IOC/IIocService.cs
index 1eedf50d..5ccfb9f8 100644
--- a/MP.Data/Services/IOC/IIocService.cs
+++ b/MP.Data/Services/IOC/IIocService.cs
@@ -30,6 +30,20 @@ namespace MP.Data.Services.IOC
///
Task ClearFusionCache();
+ ///
+ /// Esegue flush della cache fusion dato tag
+ ///
+ ///
+ ///
+ Task ClearFusionCache(string tag);
+
+ ///
+ /// Esegue flush della cache fusion data list tags
+ ///
+ ///
+ ///
+ Task ClearFusionCache(List listTags);
+
///
/// Aggiunta record MicroStato + EventList
///
diff --git a/MP.Data/Services/IOC/IocService.cs b/MP.Data/Services/IOC/IocService.cs
index fbafa6c1..f4901fb0 100644
--- a/MP.Data/Services/IOC/IocService.cs
+++ b/MP.Data/Services/IOC/IocService.cs
@@ -34,7 +34,7 @@ namespace MP.Data.Services.IOC
_repo = repo;
_scopeFactory = scopeFactory;
#if false
- _cache = cache;
+ _cache = cache;
#endif
}
@@ -58,6 +58,29 @@ namespace MP.Data.Services.IOC
return fatto;
}
+ ///
+ public async Task ClearFusionCache(string tag)
+ {
+ if (string.IsNullOrWhiteSpace(tag)) return false;
+
+ await _cache.RemoveByTagAsync(tag);
+ return true;
+ }
+
+ ///
+ public async Task ClearFusionCache(List listTags)
+ {
+ if (listTags == null || listTags.Count == 0) return false;
+
+ // Generiamo i Task di rimozione ed eseguiamoli in parallelo su Redis/L1
+ var tasks = listTags
+ .Where(tag => !string.IsNullOrWhiteSpace(tag))
+ .Select(tag => _cache.RemoveByTagAsync(tag).AsTask());
+
+ await Task.WhenAll(tasks);
+ return true;
+ }
+
///
public async Task EvListMicroStatoInsertAsync(MicroStatoMacchinaModel newRecMsm, EventListModel newRecEv)
{
@@ -79,7 +102,7 @@ namespace MP.Data.Services.IOC
else
{
result = await GetCurrOdlByProdAsync(idxMacchina);
- _redisDb.StringSet(currKey, result, GetRandTOut(redisLongTimeCache * 2));
+ _redisDb.StringSet(currKey, result, GetRandTOut(redisShortTimeCache));
}
return result;
}
@@ -109,7 +132,7 @@ namespace MP.Data.Services.IOC
}
return val != null && (val == "1" || val.ToLower() == "true");
- }, TimeSpan.FromSeconds(5));
+ }, TimeSpan.FromSeconds(5));
#endif
bool answ = false;
@@ -127,7 +150,6 @@ namespace MP.Data.Services.IOC
// provo conversione
bool.TryParse($"{rawData}", out answ);
return answ;
-
}
///
@@ -179,6 +201,7 @@ namespace MP.Data.Services.IOC
// gestisce i casi DB/REDIS secondo necessità
await CheckMicroStatoAsync(idxMacchina, valore, dataOraEvento, contatore, datiMacc);
}
+ await ClearFusionCache(idxMacchina);
// forzo RESET dati macchina...
await ResetDatiMacchinaAsync(idxMacchina);
// registro in risposta che è andato tutto bene...
@@ -246,6 +269,7 @@ namespace MP.Data.Services.IOC
answ = currCount.ToString();
// salvo per meno tempo...
await _redisDb.StringSetAsync(currKey, answ);
+ await ClearFusionCache(idxMacchina);
}
}
}
@@ -277,8 +301,6 @@ namespace MP.Data.Services.IOC
#endregion Protected Fields
- #region Protected Methods
-
#if false
///
/// Restituisce un timeout dai minuti richiesti + tempo random 1..60 sec
@@ -289,17 +311,15 @@ namespace MP.Data.Services.IOC
{
double rndValue = stdMinutes + (double)rand.Next(1, 60) / 60;
return TimeSpan.FromMinutes(rndValue);
- }
+ }
#endif
- #endregion Protected Methods
-
#region Private Fields
private static Logger Log = LogManager.GetCurrentClassLogger();
#if false
- private readonly IFusionCache _cache;
+ private readonly IFusionCache _cache;
#endif
private readonly string _className;
@@ -317,14 +337,14 @@ namespace MP.Data.Services.IOC
///
private string dtFormat = "yyyyMMddHHmmssfff";
+ #endregion Private Fields
+
#if false
private int redisLongTimeCache = 5;
- private int redisShortTimeCache = 2;
+ private int redisShortTimeCache = 2;
#endif
- #endregion Private Fields
-
#region Private Methods
///
@@ -483,7 +503,7 @@ namespace MP.Data.Services.IOC
}
///
- /// Implementa gestione recupero cache da memoria o da obj esterno + cache memoria
+ /// Implementa gestione recupero cache da memoria o da obj esterno + cache memoria (versione semplificata)
///
///
///
@@ -1020,31 +1040,37 @@ namespace MP.Data.Services.IOC
///
private async Task StatoProdMacchinaAsync(string idxMacchina, DateTime dtReq, bool forceDb = false)
{
- string cacheKey = $"IOC_StatoProd_{idxMacchina}";
+ string cKey = $"IOC_StatoProd_{idxMacchina}";
var stdTTL = TimeSpan.FromSeconds(30);
- return await GetOrFetchAsync(cacheKey, async () =>
- {
- StatoProdModel? result = new StatoProdModel();
- // cerco in _redisConn...
- string currKey = $"{MP.Data.Utils.redisStatoProd}:{idxMacchina}:{dtReq:HHmm}";
- RedisValue rawData = await _redisDb.StringGetAsync(currKey);
- if (rawData.HasValue && !forceDb)
+ return await GetOrFetchAsync(
+ operationName: "StatoProdMacchinaAsync",
+ cacheKey: cKey,
+ fetchFunc: async () =>
{
- result = JsonConvert.DeserializeObject($"{rawData}");
- }
- else
- {
- result = await _repo.StatoProdMacchinaAsync(idxMacchina, dtReq);
- // serializzo e salvo...
- rawData = JsonConvert.SerializeObject(result);
- await _redisDb.StringSetAsync(currKey, rawData, stdTTL);
- }
- if (result == null)
- {
- result = new StatoProdModel();
- }
- return result;
- }, stdTTL);
+ StatoProdModel? result = new StatoProdModel();
+ // cerco in _redisConn...
+ string currKey = $"{MP.Data.Utils.redisStatoProd}:{idxMacchina}:{dtReq:HHmm}";
+ RedisValue rawData = await _redisDb.StringGetAsync(currKey);
+ if (rawData.HasValue && !forceDb)
+ {
+ result = JsonConvert.DeserializeObject($"{rawData}");
+ }
+ else
+ {
+ result = await _repo.StatoProdMacchinaAsync(idxMacchina, dtReq);
+ // serializzo e salvo...
+ rawData = JsonConvert.SerializeObject(result);
+ await _redisDb.StringSetAsync(currKey, rawData, stdTTL);
+ }
+ if (result == null)
+ {
+ result = new StatoProdModel();
+ }
+ return result;
+ },
+ expiration: stdTTL,
+ tagList: ["IOC_StatoProd", cKey, idxMacchina]
+ );
}
///
diff --git a/MP.IOC/Controllers/IOBController.cs b/MP.IOC/Controllers/IOBController.cs
index aecb4945..834d64bd 100644
--- a/MP.IOC/Controllers/IOBController.cs
+++ b/MP.IOC/Controllers/IOBController.cs
@@ -1086,6 +1086,7 @@ namespace MP.IOC.Controllers
try
{
answ = await DService.saveCaricoPezzi(id, qty);
+ await IOCService.ClearFusionCache();
return Ok(answ);
}
catch (Exception exc)