diff --git a/MP.RIOC/MP.RIOC.csproj b/MP.RIOC/MP.RIOC.csproj
index 9c6f5aa2..6d0cd1f6 100644
--- a/MP.RIOC/MP.RIOC.csproj
+++ b/MP.RIOC/MP.RIOC.csproj
@@ -5,7 +5,7 @@
enable
enable
MP.RIOC
- 8.16.2606.1112
+ 8.16.2606.1114
diff --git a/MP.RIOC/Services/MetricsDbFlushService.cs b/MP.RIOC/Services/MetricsDbFlushService.cs
index 389626c0..10252886 100644
--- a/MP.RIOC/Services/MetricsDbFlushService.cs
+++ b/MP.RIOC/Services/MetricsDbFlushService.cs
@@ -112,10 +112,9 @@ namespace MP.RIOC.Services
var sKey = (RedisKey)$"{statKey}";
if (!TryParseKeyMetadata(sKey, out var meta) || meta.IsHourType) continue;
- //// Verifica se la chiave è "orfana" (nessun TTL o TTL troppo lungo >30gg)
- //var keyTtl = await _db.KeyTtlAsync(sKey);
- //bool isOrphanKey = keyTtl?.TotalSeconds < 0 || keyTtl?.TotalSeconds > 30.25 * 24 * 3600;
- bool isOrphanKey = false;
+ // Verifica se la chiave è "orfana" (nessun TTL o TTL troppo lungo >30gg)
+ var keyTtl = GetKeyTtl(sKey);
+ bool isOrphanKey = keyTtl?.TotalSeconds < 0 || keyTtl?.TotalSeconds > 30.25 * 24 * 3600;
// Se era scaduta o orfana e abbiamo il permesso, segnamola per la cancellazione
if ((meta.Timestamp < currentDayStart || isOrphanKey) && deleteConfirmed)
@@ -192,7 +191,7 @@ namespace MP.RIOC.Services
int deletedCount = 0;
foreach (var key in keysToDelete)
{
- batch.KeyDeleteAsync(key);
+ await batch.KeyDeleteAsync(key);
deletedCount++;
}
batch.Execute();
@@ -201,43 +200,56 @@ namespace MP.RIOC.Services
}
///
- /// Cancellazione ricorsiva chiavi ausiliarie quando si rimuove una chiave principale
- /// Rimuove :status, :errors dal sorted set e cancella le chiavi hash ausiliarie
+ /// Recupera il TTL residuo di una chiave Redis (-1 = nessun TTL, -2 = chiave non esiste)
///
- private async Task DeleteAuxKeysAndIndexAsync(RedisKey sKey, string indexKey, IBatch batch)
+ private TimeSpan? GetKeyTtl(RedisKey key)
+ {
+ try
+ {
+ return _db.KeyTimeToLive(key);
+ }
+ catch { return null; }
+ }
+
+ ///
+ /// Cancellazione ricorsiva chiavi ausiliarie (:status, :errors) e rimozione dall'indice
+ ///
+ private async Task DeleteAuxKeysAndIndexAsync(RedisKey sKey, RedisKey indexKey, IBatch batch)
{
string sKeyStr = sKey.ToString();
- string keyDir = sKeyStr.Substring(0, sKeyStr.LastIndexOf(':')); // es: MP_IOC:stats:hour:dest:method:2024061012
+ string keyDir = sKeyStr.Substring(0, sKeyStr.LastIndexOf(':'));
- // Cancella la chiave ausiliaria :status se presente
+ // Cancella :status dal sorted set e dalla hash
string statusKey = keyDir + ":status";
- RedisValue[] statusMembers = await _db.SortedSetRangeByRankAsync(indexKey, 0, -1);
- //if (statusMembers.Any(m => m.ToString() == statusKey))
- //{
- // await batch.SortedSetRemoveAsync(indexKey, statusKey);
- // await batch.KeyDeleteAsync(statusKey);
- //}
+ await batch.SortedSetRemoveAsync(indexKey, statusKey);
+ await batch.KeyDeleteAsync(statusKey);
- //// Cancella la chiave ausiliaria :errors se presente
- //string errorKey = keyDir + ":errors";
- //if (statusMembers.Any(m => m.ToString() == errorKey))
- //{
- // await batch.SortedSetRemoveAsync(indexKey, errorKey);
- // await batch.KeyDeleteAsync(errorKey);
- //}
+ // Cancella :errors dal sorted set e dalla hash
+ string errorKey = keyDir + ":errors";
+ await batch.SortedSetRemoveAsync(indexKey, errorKey);
+ await batch.KeyDeleteAsync(errorKey);
- //// Cancella anche dall'indice days se presente (per chiavi daily)
- //if (!sKeyStr.Contains(":hour:"))
- //{
- // string daysIndex = keyDir.Replace(":stats:day:", ":stats:days:")
- // .Remove(keyDir.Substring(keyDir.IndexOf(":stats:day:") + 12));
- // try
- // {
- // var dayIndexFull = $"{_redisBaseKey}:stats:days:{keyDir.Split(':')[3]}:{keyDir.Split(':')[4]}";
- // batch.SortedSetRemoveAsync(dayIndexFull, sKey);
- // }
- // catch { }
- //}
+ // Cancella chiave ausiliaria :status anche da un eventuale indice days se presente
+ if (statusKey.Contains(":stats:hours:"))
+ {
+ string daysIndex = statusKey.Replace(":stats:hours:", ":stats:days:");
+ try
+ {
+ await batch.SortedSetRemoveAsync(daysIndex, statusKey);
+ }
+ catch { }
+ }
+
+ // Cancella chiave ausiliaria :errors anche da un eventuale indice days se presente
+ if (errorKey.Contains(":stats:hours:"))
+ {
+ string daysIndex = errorKey.Replace(":stats:hours:", ":stats:days:");
+ try
+ {
+ await batch.SortedSetRemoveAsync(daysIndex, errorKey);
+ }
+ catch { }
+ }
}
///