Fix init RIOC, aggiunta fusioncache su RIOC, test con reset (da gestire meglio)
This commit is contained in:
@@ -3,7 +3,7 @@
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<Version>8.16.2606.1312</Version>
|
||||
<Version>8.16.2606.2012</Version>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<RootNamespace>MP_TAB3</RootNamespace>
|
||||
</PropertyGroup>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<body>
|
||||
<i>Modulo MAPOSPEC </i>
|
||||
<h4>Versione: 8.16.2606.1312</h4>
|
||||
<h4>Versione: 8.16.2606.2012</h4>
|
||||
<br /> Note di rilascio:
|
||||
<ul>
|
||||
<li>
|
||||
|
||||
@@ -1 +1 @@
|
||||
8.16.2606.1312
|
||||
8.16.2606.2012
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<item>
|
||||
<version>8.16.2606.1312</version>
|
||||
<version>8.16.2606.2012</version>
|
||||
<url>https://nexus.steamware.net/repository/SWS/MP-TAB3/stable/LAST/MP-TAB3.zip</url>
|
||||
<changelog>https://nexus.steamware.net/repository/SWS/MP-TAB3/stable/LAST/ChangeLog.html</changelog>
|
||||
<mandatory>false</mandatory>
|
||||
|
||||
@@ -55,6 +55,25 @@ namespace MP.Data
|
||||
return services;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Aggiunta repository/servizi specifici per RIOC
|
||||
/// </summary>
|
||||
/// <param name="services"></param>
|
||||
/// <returns></returns>
|
||||
public static IServiceCollection AddRIocDataLayer(this IServiceCollection services)
|
||||
{
|
||||
|
||||
// Repository Scoped x registrazione statistiche chiamate
|
||||
services.TryAddScoped<IStatsAggrRepository, StatsAggrRepository>();
|
||||
services.TryAddScoped<IStatsDetailRepository, StatsDetailRepository>();
|
||||
|
||||
// Servizi Scoped statistiche
|
||||
services.TryAddScoped<IStatsAggrService, StatsAggrService>();
|
||||
services.TryAddScoped<IStatsDetailService, StatsDetailService>();
|
||||
|
||||
return services;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Aggiunta repository/servizi specifici per LAND
|
||||
/// </summary>
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<RootNamespace>MP.INVE</RootNamespace>
|
||||
<Version>8.16.2606.1312</Version>
|
||||
<Version>8.16.2606.2012</Version>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<body>
|
||||
<i>Modulo MAPOINVE </i>
|
||||
<h4>Versione: 8.16.2606.1312</h4>
|
||||
<h4>Versione: 8.16.2606.2012</h4>
|
||||
<br /> Note di rilascio:
|
||||
<ul>
|
||||
<li>
|
||||
|
||||
@@ -1 +1 @@
|
||||
8.16.2606.1312
|
||||
8.16.2606.2012
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<item>
|
||||
<version>8.16.2606.1312</version>
|
||||
<version>8.16.2606.2012</version>
|
||||
<url>https://nexus.steamware.net/repository/SWS/MP-INVE/stable/LAST/MP.INVE.zip</url>
|
||||
<changelog>https://nexus.steamware.net/repository/SWS/MP-INVE/stable/LAST/ChangeLog.html</changelog>
|
||||
<mandatory>false</mandatory>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Version>8.16.2606.2010</Version>
|
||||
<Version>8.16.2606.2013</Version>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
+8
-2
@@ -107,8 +107,8 @@ builder.Services.AddSingleton<MpDataService>();
|
||||
|
||||
// 1. Registra il serializzatore NewtonsoftJson per FusionCache
|
||||
builder.Services.AddSingleton<IFusionCacheSerializer>(new FusionCacheNewtonsoftJsonSerializer());
|
||||
|
||||
// 2. Configura FusionCache (L1 Memory + L2 Redis Distributed + L3 DB via factory)
|
||||
//builder.Services.AddFusionCache("MAPO_MES_FusionCache")
|
||||
builder.Services.AddFusionCache()
|
||||
.WithDistributedCache(sp => sp.GetRequiredService<IDistributedCache>())
|
||||
.WithSerializer(new FusionCacheNewtonsoftJsonSerializer())
|
||||
@@ -119,11 +119,17 @@ builder.Services.AddFusionCache()
|
||||
.WithDefaultEntryOptions(options =>
|
||||
{
|
||||
// Durata di default dei dati in memoria
|
||||
options.Duration = TimeSpan.FromMinutes(1);
|
||||
options.Duration = TimeSpan.FromMinutes(5);
|
||||
|
||||
// Jitter: variazione casuale alla scadenza per evitare scadenze in blocco
|
||||
options.JitterMaxDuration = TimeSpan.FromSeconds(5);
|
||||
});
|
||||
//// 3. LA RIGA MAGICA: Estrae l'istanza nominata e la mappa come IFusionCache standard
|
||||
//builder.Services.AddSingleton<IFusionCache>(sp =>
|
||||
// sp.GetRequiredService<IFusionCacheProvider>().GetCache("MAPO_MES_FusionCache"));
|
||||
|
||||
// aggiunta http client x chiamare REST esterne (reset cache su RIOC, in attesa fix fusionCache)
|
||||
builder.Services.AddHttpClient();
|
||||
|
||||
logger.Info("Standard service configured");
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<body>
|
||||
<i>Modulo MP-IOC </i>
|
||||
<h4>Versione: 8.16.2606.2010</h4>
|
||||
<h4>Versione: 8.16.2606.2013</h4>
|
||||
<br /> Note di rilascio:
|
||||
<ul>
|
||||
<li>
|
||||
|
||||
@@ -1 +1 @@
|
||||
8.16.2606.2010
|
||||
8.16.2606.2013
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<item>
|
||||
<version>8.16.2606.2010</version>
|
||||
<version>8.16.2606.2013</version>
|
||||
<url>https://nexus.steamware.net/repository/SWS/MP-IOC/stable/LAST/MP.IOC.zip</url>
|
||||
<changelog>https://nexus.steamware.net/repository/SWS/MP-IOC/stable/LAST/ChangeLog.html</changelog>
|
||||
<mandatory>false</mandatory>
|
||||
|
||||
@@ -12,10 +12,12 @@ namespace MP.IOC.Services
|
||||
/// <returns></returns>
|
||||
Task<List<WeightDTO>> GetAllWeightsAsync();
|
||||
|
||||
#if false
|
||||
/// <summary>
|
||||
/// Ritorna la coppia (oldWeight, newWeight) per scegliere dove instradare il metodo tra i 2 sistemi API.
|
||||
/// </summary>
|
||||
(int oldWeight, int newWeight) GetWeightsFor(string method);
|
||||
(int oldWeight, int newWeight) GetWeightsFor(string method);
|
||||
#endif
|
||||
|
||||
/// <summary>
|
||||
/// Aggiorna/Aggiuinge il valore del weight richiesto
|
||||
|
||||
@@ -16,11 +16,13 @@ namespace MP.IOC.Services
|
||||
_defaultNew = config.GetValue<int>("RouteMan:DefaultWeightNew", 0);
|
||||
}
|
||||
|
||||
#if false
|
||||
public (int oldWeight, int newWeight) GetWeightsFor(string method)
|
||||
{
|
||||
if (string.IsNullOrEmpty(method)) method = "unknown";
|
||||
return _map.GetOrAdd(method, _ => (_defaultOld, _defaultNew));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
public void SetWeights(string method, int oldWeight, int newWeight)
|
||||
{
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
using MP.Core.DTO;
|
||||
using NLog;
|
||||
using StackExchange.Redis;
|
||||
using ZiggyCreatures.Caching.Fusion;
|
||||
|
||||
namespace MP.IOC.Services
|
||||
{
|
||||
@@ -7,14 +9,23 @@ namespace MP.IOC.Services
|
||||
{
|
||||
#region Public Constructors
|
||||
|
||||
public RedisWeightProvider(IConnectionMultiplexer mux, IConfiguration config)
|
||||
public RedisWeightProvider(
|
||||
IConnectionMultiplexer mux,
|
||||
IFusionCache cache,
|
||||
IHttpClientFactory httpClientFactory,
|
||||
IConfiguration config)
|
||||
{
|
||||
_cache = cache;
|
||||
_config = config;
|
||||
_httpClientFactory = httpClientFactory;
|
||||
_db = mux.GetDatabase();
|
||||
_mux = mux;
|
||||
_defaultOld = config.GetValue<int>("RouteMan:DefaultWeightOld", 100);
|
||||
_defaultNew = config.GetValue<int>("RouteMan:DefaultWeightNew", 0);
|
||||
_redisBaseKey = config.GetValue<string>("ServerConf:RedisBaseKey") ?? "MP_IOC";
|
||||
// Leggiamo l'URL base del gateway dal file di configurazione dell'Admin
|
||||
// es. "https://10.74.83.100:5290/MP/RIOC/api/admin/cache/purge-route/"
|
||||
_gatewayPurgeUrl = config.GetValue<string>("ServerConf:GatewayPurgeUrl") ?? "https://localhost:7120/MP/RIOC/api/admin/cache/purge-route/";
|
||||
_keyPrefix = $"{_redisBaseKey}:route_weight:";
|
||||
}
|
||||
|
||||
@@ -22,6 +33,140 @@ namespace MP.IOC.Services
|
||||
|
||||
#region Public Methods
|
||||
|
||||
public async Task<List<WeightDTO>> GetAllWeightsAsync()
|
||||
{
|
||||
var result = new List<WeightDTO>();
|
||||
var server = _mux.GetServer(_mux.GetEndPoints().First());
|
||||
|
||||
if (server.IsReplica)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
await foreach (var key in server.KeysAsync(pattern: $"{_keyPrefix}*"))
|
||||
{
|
||||
var methodName = KeyToString(key.ToString());
|
||||
if (string.IsNullOrEmpty(methodName)) continue;
|
||||
|
||||
var oldVal = _db.HashGet(key, "old");
|
||||
var newVal = _db.HashGet(key, "new");
|
||||
|
||||
int oldW = 100;
|
||||
int newW = 0;
|
||||
|
||||
if (!oldVal.IsNull && int.TryParse(oldVal.ToString(), out var parsedOld))
|
||||
oldW = Math.Clamp(parsedOld, 0, 100);
|
||||
|
||||
if (!newVal.IsNull && int.TryParse(newVal.ToString(), out var parsedNew))
|
||||
newW = Math.Clamp(parsedNew, 0, 100);
|
||||
|
||||
result.Add(new WeightDTO { Method = methodName, OldWeight = oldW, NewWeight = newW });
|
||||
}
|
||||
|
||||
// riordino desc x NEW poi alfabetico...
|
||||
result = result
|
||||
.OrderByDescending(x => x.NewWeight)
|
||||
.ThenBy(x => x.Method)
|
||||
.ToList();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// API per aggiornare i pesi a runtime (opzionale)
|
||||
public void SetWeights(string method, int oldWeight, int newWeight)
|
||||
{
|
||||
var key = _keyPrefix + (string.IsNullOrEmpty(method) ? "unknown" : method);
|
||||
_db.HashSet(key, new HashEntry[] {
|
||||
new HashEntry("old", Math.Clamp(oldWeight,0,100)),
|
||||
new HashEntry("new", Math.Clamp(newWeight,0,100))
|
||||
});
|
||||
|
||||
ResetFusionCache(method);
|
||||
}
|
||||
|
||||
public bool UpsertWeight(WeightDTO updRecord)
|
||||
{
|
||||
if (updRecord == null || string.IsNullOrEmpty(updRecord.Method))
|
||||
return false;
|
||||
|
||||
// 1. Scrivi su Redis (Sorgente dati reale)
|
||||
var key = _keyPrefix + updRecord.Method;
|
||||
_db.HashSet(key, new HashEntry[] {
|
||||
new HashEntry("old", Math.Clamp(updRecord.OldWeight, 0, 100)),
|
||||
new HashEntry("new", Math.Clamp(updRecord.NewWeight, 0, 100))
|
||||
});
|
||||
|
||||
ResetFusionCache(updRecord.Method);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#endregion Public Methods
|
||||
|
||||
#region Private Fields
|
||||
|
||||
private static string _keyPrefix = "route_weight:";
|
||||
private static string _redisBaseKey = "";
|
||||
private static Logger Log = LogManager.GetCurrentClassLogger();
|
||||
private readonly IFusionCache _cache;
|
||||
private readonly IConfiguration _config;
|
||||
private readonly IDatabase _db;
|
||||
private readonly int _defaultNew;
|
||||
private readonly int _defaultOld;
|
||||
private readonly string _gatewayPurgeUrl;
|
||||
private readonly IHttpClientFactory _httpClientFactory;
|
||||
private readonly IConnectionMultiplexer _mux;
|
||||
|
||||
#endregion Private Fields
|
||||
|
||||
#region Private Methods
|
||||
|
||||
private string KeyToString(string key)
|
||||
{
|
||||
if (string.IsNullOrEmpty(key)) return "";
|
||||
var prefix = _keyPrefix ?? "";
|
||||
if (key.StartsWith(prefix))
|
||||
return key.Substring(prefix.Length);
|
||||
return key;
|
||||
}
|
||||
|
||||
private void ResetFusionCache(string method)
|
||||
{
|
||||
//try
|
||||
//{
|
||||
// // Sfrutta la factory per prendere un client ottimizzato e pulito
|
||||
// using var client = _httpClientFactory.CreateClient();
|
||||
|
||||
// // Componiamo l'URL finale pulito (es. .../purge-route/SIMUL_01)
|
||||
// var finalUrl = $"{_gatewayPurgeUrl.TrimEnd('/')}/{updRecord.Method}";
|
||||
|
||||
// // Inviamo la POST (passiamo null come HttpContent perché non serve un Body)
|
||||
// var response = client.PostAsync(finalUrl, null);
|
||||
|
||||
// if (response.IsSuccessStatusCode)
|
||||
// {
|
||||
// Log.Info($"[CACHE] Sfratto RAM notificato con successo al Gateway per il metodo: {updRecord.Method}");
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// Log.Warn($"[CACHE] Il gateway ha risposto con codice {response.StatusCode} alla purga di {updRecord.Method}");
|
||||
// }
|
||||
//}
|
||||
//catch (Exception ex)
|
||||
//{
|
||||
// // Usiamo un log di errore ma non blocchiamo l'applicazione Admin
|
||||
// // se il gateway in quel momento fosse offline o irraggiungibile
|
||||
// Log.Error(ex, $"[CACHE] Impossibile raggiungere il gateway per spurgare la rotta: {updRecord.Method}");
|
||||
//}
|
||||
|
||||
// Grazie al Backplane Pub/Sub, la RAM verrà azzerata istantaneamente su TUTTI i server.
|
||||
var cacheKey = $"weights:{method}";
|
||||
_cache.Remove(cacheKey);
|
||||
}
|
||||
|
||||
#endregion Private Methods
|
||||
|
||||
#if false
|
||||
/// <summary>
|
||||
/// Ritorna (oldWeight, newWeight) per il metodo. Se non esiste, crea la chiave con i default.
|
||||
/// </summary>
|
||||
@@ -67,91 +212,6 @@ namespace MP.IOC.Services
|
||||
|
||||
return (oldW, newW);
|
||||
}
|
||||
|
||||
// API per aggiornare i pesi a runtime (opzionale)
|
||||
public void SetWeights(string method, int oldWeight, int newWeight)
|
||||
{
|
||||
var key = _keyPrefix + (string.IsNullOrEmpty(method) ? "unknown" : method);
|
||||
_db.HashSet(key, new HashEntry[] {
|
||||
new HashEntry("old", Math.Clamp(oldWeight,0,100)),
|
||||
new HashEntry("new", Math.Clamp(newWeight,0,100))
|
||||
});
|
||||
}
|
||||
|
||||
public async Task<List<WeightDTO>> GetAllWeightsAsync()
|
||||
{
|
||||
var result = new List<WeightDTO>();
|
||||
var server = _mux.GetServer(_mux.GetEndPoints().First());
|
||||
|
||||
if (server.IsReplica)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
await foreach (var key in server.KeysAsync(pattern: $"{_keyPrefix}*"))
|
||||
{
|
||||
var methodName = KeyToString(key.ToString());
|
||||
if (string.IsNullOrEmpty(methodName)) continue;
|
||||
|
||||
var oldVal = _db.HashGet(key, "old");
|
||||
var newVal = _db.HashGet(key, "new");
|
||||
|
||||
int oldW = 100;
|
||||
int newW = 0;
|
||||
|
||||
if (!oldVal.IsNull && int.TryParse(oldVal.ToString(), out var parsedOld))
|
||||
oldW = Math.Clamp(parsedOld, 0, 100);
|
||||
|
||||
if (!newVal.IsNull && int.TryParse(newVal.ToString(), out var parsedNew))
|
||||
newW = Math.Clamp(parsedNew, 0, 100);
|
||||
|
||||
result.Add(new WeightDTO { Method = methodName, OldWeight = oldW, NewWeight = newW });
|
||||
}
|
||||
|
||||
// riordino desc x NEW poi alfabetico...
|
||||
result = result
|
||||
.OrderByDescending(x => x.NewWeight)
|
||||
.ThenBy(x => x.Method)
|
||||
.ToList();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public bool UpsertWeight(WeightDTO updRecord)
|
||||
{
|
||||
if (updRecord == null || string.IsNullOrEmpty(updRecord.Method))
|
||||
return false;
|
||||
|
||||
var key = _keyPrefix + updRecord.Method;
|
||||
_db.HashSet(key, new HashEntry[] {
|
||||
new HashEntry("old", Math.Clamp(updRecord.OldWeight, 0, 100)),
|
||||
new HashEntry("new", Math.Clamp(updRecord.NewWeight, 0, 100))
|
||||
});
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private string KeyToString(string key)
|
||||
{
|
||||
if (string.IsNullOrEmpty(key)) return "";
|
||||
var prefix = _keyPrefix ?? "";
|
||||
if (key.StartsWith(prefix))
|
||||
return key.Substring(prefix.Length);
|
||||
return key;
|
||||
}
|
||||
|
||||
#endregion Public Methods
|
||||
|
||||
#region Private Fields
|
||||
|
||||
private static string _keyPrefix = "route_weight:";
|
||||
private static string _redisBaseKey = "";
|
||||
private readonly IConfiguration _config;
|
||||
private readonly IDatabase _db;
|
||||
private readonly IConnectionMultiplexer _mux;
|
||||
private readonly int _defaultNew;
|
||||
private readonly int _defaultOld;
|
||||
|
||||
#endregion Private Fields
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -16,6 +16,7 @@
|
||||
"mdbConnString": "mongodb://localhost:27017"
|
||||
},
|
||||
"ServerConf": {
|
||||
"GatewayPurgeUrl": "http://maposrv.egalware.com/MP/RIOC/api/admin/cache/purge-route/",
|
||||
"useFactory": false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -64,6 +64,7 @@
|
||||
},
|
||||
"ServerConf": {
|
||||
"BaseUrlIoc": "/MP/IOC/",
|
||||
"GatewayPurgeUrl": "http://iis01.egalware.com/MP/RIOC/api/admin/cache/purge-route/",
|
||||
"MpIoNS": "MoonPro:SQL2016DEV:MoonPro",
|
||||
"RedisBaseKey": "MP-IOC",
|
||||
"RedisWeight": true,
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<RootNamespace>MP.Land</RootNamespace>
|
||||
<Version>8.16.2606.1312</Version>
|
||||
<Version>8.16.2606.2012</Version>
|
||||
<Configurations>Debug;Release;Debug_LiManDebug</Configurations>
|
||||
<SatelliteResourceLanguages>en</SatelliteResourceLanguages>
|
||||
<RunAnalyzersDuringBuild>True</RunAnalyzersDuringBuild>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<body>
|
||||
<i>Modulo Tablet MAPO - DotNet6</i>
|
||||
<h4>Versione: 8.16.2606.1312</h4>
|
||||
<h4>Versione: 8.16.2606.2012</h4>
|
||||
<br />
|
||||
Note di rilascio:
|
||||
<ul>
|
||||
|
||||
@@ -1 +1 @@
|
||||
8.16.2606.1312
|
||||
8.16.2606.2012
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<item>
|
||||
<version>8.16.2606.1312</version>
|
||||
<version>8.16.2606.2012</version>
|
||||
<url>https://nexus.steamware.net/repository/SWS/MP-LAND/stable/LAST/MP.Land.zip</url>
|
||||
<changelog>https://nexus.steamware.net/repository/SWS/MP-LAND/stable/LAST/ChangeLog.html</changelog>
|
||||
<mandatory>false</mandatory>
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<RootNamespace>MP.MON</RootNamespace>
|
||||
<AssemblyName>$(AssemblyName.Replace(' ', '_'))</AssemblyName>
|
||||
<Version>8.16.2606.1312</Version>
|
||||
<Version>8.16.2606.2012</Version>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<body>
|
||||
<i>Modulo MAPOSPEC </i>
|
||||
<h4>Versione: 8.16.2606.1312</h4>
|
||||
<h4>Versione: 8.16.2606.2012</h4>
|
||||
<br /> Note di rilascio:
|
||||
<ul>
|
||||
<li>
|
||||
|
||||
@@ -1 +1 @@
|
||||
8.16.2606.1312
|
||||
8.16.2606.2012
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<item>
|
||||
<version>8.16.2606.1312</version>
|
||||
<version>8.16.2606.2012</version>
|
||||
<url>https://nexus.steamware.net/repository/SWS/MP-MON/stable/LAST/MP.MON.zip</url>
|
||||
<changelog>https://nexus.steamware.net/repository/SWS/MP-MON/stable/LAST/ChangeLog.html</changelog>
|
||||
<mandatory>false</mandatory>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<RootNamespace>MP.Prog</RootNamespace>
|
||||
<Version>8.16.2606.1312</Version>
|
||||
<Version>8.16.2606.2012</Version>
|
||||
<GenerateDocumentationFile>True</GenerateDocumentationFile>
|
||||
</PropertyGroup>
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<body>
|
||||
<i>Modulo gestione Programmi MAPO</i>
|
||||
<h4>Versione: 8.16.2606.1312</h4>
|
||||
<h4>Versione: 8.16.2606.2012</h4>
|
||||
<br />
|
||||
Note di rilascio:
|
||||
<ul>
|
||||
|
||||
@@ -1 +1 @@
|
||||
8.16.2606.1312
|
||||
8.16.2606.2012
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<item>
|
||||
<version>8.16.2606.1312</version>
|
||||
<version>8.16.2606.2012</version>
|
||||
<url>https://nexus.steamware.net/repository/SWS/MP-PROG/stable/LAST/MP.Prog.zip</url>
|
||||
<changelog>https://nexus.steamware.net/repository/SWS/MP-PROG/stable/LAST/ChangeLog.html</changelog>
|
||||
<mandatory>false</mandatory>
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<RootNamespace>MP.RIOC</RootNamespace>
|
||||
<Version>8.16.2606.1312</Version>
|
||||
<Version>8.16.2606.2013</Version>
|
||||
<AspNetCoreHostingModel>InProcess</AspNetCoreHostingModel>
|
||||
</PropertyGroup>
|
||||
|
||||
|
||||
+65
-35
@@ -1,5 +1,5 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Diagnostics;
|
||||
using Microsoft.Extensions.Caching.Distributed;
|
||||
using MP.Core.Conf;
|
||||
using MP.Data;
|
||||
using MP.RIOC.Services;
|
||||
@@ -9,6 +9,10 @@ using StackExchange.Redis;
|
||||
using System.Diagnostics;
|
||||
using System.Net;
|
||||
using System.Reflection;
|
||||
using ZiggyCreatures.Caching.Fusion;
|
||||
using ZiggyCreatures.Caching.Fusion.Backplane.StackExchangeRedis;
|
||||
using ZiggyCreatures.Caching.Fusion.Serialization;
|
||||
using ZiggyCreatures.Caching.Fusion.Serialization.NewtonsoftJson;
|
||||
|
||||
|
||||
// Forza il ThreadPool a tenere pronti almeno 500 thread per i calcoli e 500 per l'I/O di rete
|
||||
@@ -19,6 +23,11 @@ var builder = WebApplication.CreateBuilder(args);
|
||||
// RECUPERO L'AMBIENTE REALE (Che ora IIS passa correttamente come 'Staging')
|
||||
var env = builder.Environment;
|
||||
|
||||
// recupero env corrente
|
||||
var logger = LogManager.Setup()
|
||||
.LoadConfigurationFromAppSettings()
|
||||
.GetCurrentClassLogger();
|
||||
|
||||
// FORZA IL CARICAMENTO CORRETTO DEI JSON CON LA GERARCHIA DI AMBIENTE
|
||||
builder.Configuration
|
||||
.SetBasePath(env.ContentRootPath)
|
||||
@@ -26,10 +35,6 @@ builder.Configuration
|
||||
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true)
|
||||
.AddEnvironmentVariables();
|
||||
|
||||
// recupero env corrente
|
||||
var logger = LogManager.Setup()
|
||||
.LoadConfigurationFromAppSettings()
|
||||
.GetCurrentClassLogger();
|
||||
|
||||
builder.Logging.ClearProviders();
|
||||
builder.Host.UseNLog();
|
||||
@@ -50,29 +55,14 @@ builder.Services.Configure<RedisScriptsConfig>(
|
||||
builder.Configuration.GetSection("RedisScripts"));
|
||||
logger.Info("RedisScript Provider configured");
|
||||
|
||||
// Metodi principali x accesso dati
|
||||
var connStr = builder.Configuration.GetConnectionString("MP.Data")
|
||||
?? throw new InvalidOperationException("ConnString 'MP.Data' mancante.");
|
||||
builder.Services.AddDbContextFactory<MoonProContext>(options =>
|
||||
options.UseSqlServer(connStr)
|
||||
.EnableSensitiveDataLogging(false) // true solo in Sviluppo
|
||||
.ConfigureWarnings(w => w.Ignore(CoreEventId.ManyServiceProvidersCreatedWarning)));
|
||||
var connStrFL = builder.Configuration.GetConnectionString("MP.Flux")
|
||||
?? throw new InvalidOperationException("ConnString 'MP.Flux' mancante.");
|
||||
builder.Services.AddDbContextFactory<MoonPro_FluxContext>(options =>
|
||||
options.UseSqlServer(connStrFL)
|
||||
.EnableSensitiveDataLogging(false) // true solo in Sviluppo
|
||||
.ConfigureWarnings(w => w.Ignore(CoreEventId.ManyServiceProvidersCreatedWarning)));
|
||||
|
||||
// MP.Data DbContext for Stats repositories
|
||||
string utilsConnString = builder.Configuration.GetConnectionString("MP.Utils") ?? "Server=localhost;Database=MoonPro_Utils; integrated security=True; MultipleActiveResultSets=True; App=MP.IOC;";
|
||||
builder.Services.AddDbContextFactory<MoonPro_UtilsContext>(options =>
|
||||
options.UseSqlServer(utilsConnString));
|
||||
|
||||
// MP.Data Services Utils - Statistiche DB
|
||||
builder.Services.AddIocDataLayer();
|
||||
builder.Services.AddRIocDataLayer();
|
||||
|
||||
// 1. Configurazione dell'invoker personalizzato (Risolve i tuoi errori)
|
||||
// 1. Configurazione dell'invoker personalizzato (Potenziato con il Pooling)
|
||||
var httpClientInvoker = new HttpMessageInvoker(new SocketsHttpHandler
|
||||
{
|
||||
@@ -109,8 +99,28 @@ builder.Services.AddHttpForwarder();
|
||||
var redisMux = ConnectionMultiplexer.Connect(confRedis);
|
||||
builder.Services.AddSingleton<IConnectionMultiplexer>(redisMux);
|
||||
|
||||
// registrazione FusionCache
|
||||
builder.Services.AddFusionCache();
|
||||
// 1. Registra il serializzatore NewtonsoftJson per FusionCache
|
||||
builder.Services.AddSingleton<IFusionCacheSerializer>(new FusionCacheNewtonsoftJsonSerializer());
|
||||
// 2. Configura FusionCache (L1 Memory + L2 Redis Distributed + L3 DB via factory)
|
||||
//builder.Services.AddFusionCache("MAPO_MES_FusionCache")
|
||||
builder.Services.AddFusionCache()
|
||||
.WithDistributedCache(sp => sp.GetRequiredService<IDistributedCache>())
|
||||
.WithSerializer(new FusionCacheNewtonsoftJsonSerializer())
|
||||
.WithBackplane(new RedisBackplane(new RedisBackplaneOptions
|
||||
{
|
||||
ConnectionMultiplexerFactory = () => Task.FromResult<IConnectionMultiplexer>(redisMux)
|
||||
}))
|
||||
.WithDefaultEntryOptions(options =>
|
||||
{
|
||||
// Durata di default dei dati in memoria
|
||||
options.Duration = TimeSpan.FromMinutes(5);
|
||||
|
||||
// Jitter: variazione casuale alla scadenza per evitare scadenze in blocco
|
||||
options.JitterMaxDuration = TimeSpan.FromSeconds(5);
|
||||
});
|
||||
//// 3. LA RIGA MAGICA: Estrae l'istanza nominata e la mappa come IFusionCache standard
|
||||
//builder.Services.AddSingleton<IFusionCache>(sp =>
|
||||
// sp.GetRequiredService<IFusionCacheProvider>().GetCache("MAPO_MES_FusionCache"));
|
||||
|
||||
// Registrazione dei servizi custom
|
||||
builder.Services.AddSingleton<PreserveBodyTransformer>();
|
||||
@@ -175,6 +185,38 @@ app.Use(async (ctx, next) =>
|
||||
await next();
|
||||
});
|
||||
|
||||
|
||||
// test per ambiente di esecuzione InProcess...
|
||||
app.MapGet("api/alive", () =>
|
||||
$"OK - Girando in: {System.Diagnostics.Process.GetCurrentProcess().ProcessName}");
|
||||
|
||||
app.MapGet("/router-status", (RouteStatsManager stats) => Results.Ok(new
|
||||
{
|
||||
Status = "Online",
|
||||
Version = assemblyVersion,
|
||||
Mode = weightOnRedis ? "Redis" : "InMemory",
|
||||
Time = DateTime.Now,
|
||||
Metrics = stats.Snapshot()
|
||||
}));
|
||||
|
||||
// Endpoint per la rimozione mirata di una singola rotta dalla cache
|
||||
app.MapPost("/api/admin/cache/purge-route/{method}", (string method, IWeightProvider weightProvider) =>
|
||||
{
|
||||
try
|
||||
{
|
||||
if (weightProvider is RedisWeightProvider redisProvider)
|
||||
{
|
||||
redisProvider.EvictLocalCacheFor(method);
|
||||
return Results.Ok(new { Success = true, Message = $"Cache RAM per '{method}' svuotata." });
|
||||
}
|
||||
return Results.Problem("Provider non valido.");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return Results.Problem($"Errore: {ex.Message}");
|
||||
}
|
||||
});
|
||||
|
||||
// 5. Il cuore del Proxy (MapWhen è terminale per le richieste che lo soddisfano)
|
||||
string routePath = configuration.GetValue<string>("ServerConf:RoutePath") ?? "/api/IOB";
|
||||
string fullPath = $"{baseUrl}{routePath}".Replace("//", "/");
|
||||
@@ -189,22 +231,10 @@ app.MapWhen(ctx => ctx.Request.Path.StartsWithSegments(routePath, StringComparis
|
||||
});
|
||||
});
|
||||
|
||||
// test per ambiente di esecuzione InProcess...
|
||||
app.MapGet("api/alive", () =>
|
||||
$"OK - Girando in: {System.Diagnostics.Process.GetCurrentProcess().ProcessName}");
|
||||
|
||||
// 6. Definizione degli Endpoints locali
|
||||
app.MapRazorPages();
|
||||
|
||||
app.MapGet("/router-status", (RouteStatsManager stats) => Results.Ok(new
|
||||
{
|
||||
Status = "Online",
|
||||
Version = assemblyVersion,
|
||||
Mode = weightOnRedis ? "Redis" : "InMemory",
|
||||
Time = DateTime.Now,
|
||||
Metrics = stats.Snapshot()
|
||||
}));
|
||||
|
||||
// 7. Fallback "intelligente"
|
||||
// Invece di app.Run, usiamo MapFallback che viene eseguito SOLO se nessun altro endpoint o MapWhen ha risposto
|
||||
app.MapFallback(async context =>
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
"dotnetRunMessages": true,
|
||||
"launchBrowser": true,
|
||||
"launchUrl": "MP/RIOC/api/IOB/",
|
||||
"applicationUrl": "http://localhost:5290",
|
||||
"applicationUrl": "http://*:5290",
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
}
|
||||
@@ -24,7 +24,7 @@
|
||||
"dotnetRunMessages": true,
|
||||
"launchBrowser": true,
|
||||
"launchUrl": "MP/RIOC/api/IOB/",
|
||||
"applicationUrl": "https://localhost:7120;http://localhost:5290",
|
||||
"applicationUrl": "https://*:7120;http://*:5290",
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<body>
|
||||
<i>Modulo MP-RIOC </i>
|
||||
<h4>Versione: 8.16.2606.1312</h4>
|
||||
<h4>Versione: 8.16.2606.2013</h4>
|
||||
<br /> Note di rilascio:
|
||||
<ul>
|
||||
<li>
|
||||
|
||||
@@ -1 +1 @@
|
||||
8.16.2606.1312
|
||||
8.16.2606.2013
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<item>
|
||||
<version>8.16.2606.1312</version>
|
||||
<version>8.16.2606.2013</version>
|
||||
<url>https://nexus.steamware.net/repository/SWS/MP-RIOC/stable/LAST/MP.RIOC.zip</url>
|
||||
<changelog>https://nexus.steamware.net/repository/SWS/MP-RIOC/stable/LAST/ChangeLog.html</changelog>
|
||||
<mandatory>false</mandatory>
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using MP.Core.DTO;
|
||||
using StackExchange.Redis;
|
||||
using ZiggyCreatures.Caching.Fusion;
|
||||
|
||||
namespace MP.RIOC.Services
|
||||
{
|
||||
@@ -7,8 +8,12 @@ namespace MP.RIOC.Services
|
||||
{
|
||||
#region Public Constructors
|
||||
|
||||
public RedisWeightProvider(IConnectionMultiplexer mux, IConfiguration config)
|
||||
public RedisWeightProvider(
|
||||
IConnectionMultiplexer mux,
|
||||
IFusionCache cache,
|
||||
IConfiguration config)
|
||||
{
|
||||
_cache = cache;
|
||||
_config = config;
|
||||
_db = mux.GetDatabase();
|
||||
_mux = mux;
|
||||
@@ -23,59 +28,17 @@ namespace MP.RIOC.Services
|
||||
#region Public Methods
|
||||
|
||||
/// <summary>
|
||||
/// Ritorna (oldWeight, newWeight) per il metodo. Se non esiste, crea la chiave con i default.
|
||||
/// Eliminazione esplicita cache data chiave
|
||||
/// </summary>
|
||||
public (int oldWeight, int newWeight) GetWeightsFor(string method)
|
||||
/// <param name="method"></param>
|
||||
public void EvictLocalCacheFor(string method)
|
||||
{
|
||||
if (string.IsNullOrEmpty(method)) method = "unknown";
|
||||
var key = _keyPrefix + method;
|
||||
if (string.IsNullOrEmpty(method)) return;
|
||||
|
||||
// Leggi entrambi i campi
|
||||
var oldVal = _db.HashGet(key, "old");
|
||||
var newVal = _db.HashGet(key, "new");
|
||||
var cacheKey = $"weights:{method}";
|
||||
|
||||
// Se entrambi mancanti, inizializza con default (usando HSet con When.NotExists per evitare overwrite)
|
||||
if (oldVal.IsNull && newVal.IsNull)
|
||||
{
|
||||
// Imposta i campi singolarmente con When.NotExists per evitare overwrite
|
||||
_db.HashSet(key, "old", _defaultOld, When.NotExists);
|
||||
_db.HashSet(key, "new", _defaultNew, When.NotExists);
|
||||
|
||||
// Rileggi per essere sicuri
|
||||
oldVal = _db.HashGet(key, "old");
|
||||
newVal = _db.HashGet(key, "new");
|
||||
}
|
||||
|
||||
// Se uno dei due manca, impostalo al default (non sovrascrive l'altro)
|
||||
if (oldVal.IsNull)
|
||||
{
|
||||
_db.HashSet(key, "old", _defaultOld, When.NotExists);
|
||||
oldVal = _defaultOld;
|
||||
}
|
||||
if (newVal.IsNull)
|
||||
{
|
||||
_db.HashSet(key, "new", _defaultNew, When.NotExists);
|
||||
newVal = _defaultNew;
|
||||
}
|
||||
|
||||
if (!int.TryParse(oldVal.ToString(), out var oldW)) oldW = _defaultOld;
|
||||
if (!int.TryParse(newVal.ToString(), out var newW)) newW = _defaultNew;
|
||||
|
||||
// clamp 0..100
|
||||
oldW = Math.Clamp(oldW, 0, 100);
|
||||
newW = Math.Clamp(newW, 0, 100);
|
||||
|
||||
return (oldW, newW);
|
||||
}
|
||||
|
||||
// API per aggiornare i pesi a runtime (opzionale)
|
||||
public void SetWeights(string method, int oldWeight, int newWeight)
|
||||
{
|
||||
var key = _keyPrefix + (string.IsNullOrEmpty(method) ? "unknown" : method);
|
||||
_db.HashSet(key, new HashEntry[] {
|
||||
new HashEntry("old", Math.Clamp(oldWeight,0,100)),
|
||||
new HashEntry("new", Math.Clamp(newWeight,0,100))
|
||||
});
|
||||
// Rimuove la chiave dalla RAM (L1) dell'istanza corrente del Gateway
|
||||
_cache.Remove(cacheKey);
|
||||
}
|
||||
|
||||
public async Task<List<WeightDTO>> GetAllWeightsAsync()
|
||||
@@ -117,20 +80,164 @@ namespace MP.RIOC.Services
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Ritorna (oldWeight, newWeight) per il metodo con FusionCache e poi con dati Redis.
|
||||
/// Se non esiste, crea la chiave con i default value.
|
||||
/// </summary>
|
||||
public (int oldWeight, int newWeight) GetWeightsFor(string method)
|
||||
{
|
||||
if (string.IsNullOrEmpty(method)) method = "unknown";
|
||||
|
||||
var cacheKey = $"weights:{method}";
|
||||
|
||||
// FusionCache gestisce L1, L2 e se non trova nulla esegue la factory sotto
|
||||
var weights = _cache.GetOrSet<RouteWeights>(
|
||||
cacheKey,
|
||||
_ =>
|
||||
{
|
||||
// FACTORY DI INIZIALIZZAZIONE (Viene eseguita solo se la cache è vuota ovunque)
|
||||
var redisKey = _keyPrefix + method;
|
||||
var oldVal = _db.HashGet(redisKey, "old");
|
||||
var newVal = _db.HashGet(redisKey, "new");
|
||||
|
||||
if (oldVal.IsNull && newVal.IsNull)
|
||||
{
|
||||
_db.HashSet(redisKey, "old", _defaultOld, When.NotExists);
|
||||
_db.HashSet(redisKey, "new", _defaultNew, When.NotExists);
|
||||
oldVal = _defaultOld;
|
||||
newVal = _defaultNew;
|
||||
}
|
||||
|
||||
if (oldVal.IsNull) { _db.HashSet(redisKey, "old", _defaultOld, When.NotExists); oldVal = _defaultOld; }
|
||||
if (newVal.IsNull) { _db.HashSet(redisKey, "new", _defaultNew, When.NotExists); newVal = _defaultNew; }
|
||||
|
||||
if (!int.TryParse(oldVal.ToString(), out var oldW)) oldW = _defaultOld;
|
||||
if (!int.TryParse(newVal.ToString(), out var newW)) newW = _defaultNew;
|
||||
|
||||
return new RouteWeights(Math.Clamp(oldW, 0, 100), Math.Clamp(newW, 0, 100));
|
||||
},
|
||||
// Durata specifica per questa tipologia di dato
|
||||
options => options.SetDuration(TimeSpan.FromMinutes(10))
|
||||
);
|
||||
|
||||
return (weights.OldWeight, weights.NewWeight);
|
||||
|
||||
#if false
|
||||
var key = _keyPrefix + method;
|
||||
|
||||
// Leggi entrambi i campi
|
||||
var oldVal = _db.HashGet(key, "old");
|
||||
var newVal = _db.HashGet(key, "new");
|
||||
|
||||
// Se entrambi mancanti, inizializza con default (usando HSet con When.NotExists per evitare overwrite)
|
||||
if (oldVal.IsNull && newVal.IsNull)
|
||||
{
|
||||
// Imposta i campi singolarmente con When.NotExists per evitare overwrite
|
||||
_db.HashSet(key, "old", _defaultOld, When.NotExists);
|
||||
_db.HashSet(key, "new", _defaultNew, When.NotExists);
|
||||
|
||||
// Rileggi per essere sicuri
|
||||
oldVal = _db.HashGet(key, "old");
|
||||
newVal = _db.HashGet(key, "new");
|
||||
}
|
||||
|
||||
// Se uno dei due manca, impostalo al default (non sovrascrive l'altro)
|
||||
if (oldVal.IsNull)
|
||||
{
|
||||
_db.HashSet(key, "old", _defaultOld, When.NotExists);
|
||||
oldVal = _defaultOld;
|
||||
}
|
||||
if (newVal.IsNull)
|
||||
{
|
||||
_db.HashSet(key, "new", _defaultNew, When.NotExists);
|
||||
newVal = _defaultNew;
|
||||
}
|
||||
|
||||
if (!int.TryParse(oldVal.ToString(), out var oldW)) oldW = _defaultOld;
|
||||
if (!int.TryParse(newVal.ToString(), out var newW)) newW = _defaultNew;
|
||||
|
||||
// clamp 0..100
|
||||
oldW = Math.Clamp(oldW, 0, 100);
|
||||
newW = Math.Clamp(newW, 0, 100);
|
||||
|
||||
return (oldW, newW);
|
||||
#endif
|
||||
}
|
||||
|
||||
// API per aggiornare i pesi a runtime (opzionale)
|
||||
public void SetWeights(string method, int oldWeight, int newWeight)
|
||||
{
|
||||
// 1. Scrittura su Redis
|
||||
var key = _keyPrefix + (string.IsNullOrEmpty(method) ? "unknown" : method);
|
||||
_db.HashSet(key, new HashEntry[] {
|
||||
new HashEntry("old", Math.Clamp(oldWeight,0,100)),
|
||||
new HashEntry("new", Math.Clamp(newWeight,0,100))
|
||||
});
|
||||
|
||||
// 2. 🚀 COORDINAZIONE: Rimuovi la chiave da FusionCache.
|
||||
// Grazie al Backplane Pub/Sub, la RAM verrà azzerata istantaneamente su TUTTI i server.
|
||||
var cacheKey = $"weights:{method}";
|
||||
_cache.Remove(cacheKey);
|
||||
}
|
||||
|
||||
public bool UpsertWeight(WeightDTO updRecord)
|
||||
{
|
||||
if (updRecord == null || string.IsNullOrEmpty(updRecord.Method))
|
||||
return false;
|
||||
|
||||
var key = _keyPrefix + updRecord.Method;
|
||||
_db.HashSet(key, new HashEntry[] {
|
||||
new HashEntry("old", Math.Clamp(updRecord.OldWeight, 0, 100)),
|
||||
new HashEntry("new", Math.Clamp(updRecord.NewWeight, 0, 100))
|
||||
});
|
||||
// 1. Scrivi su Redis (Sorgente dati reale)
|
||||
var redisKey = _keyPrefix + updRecord.Method;
|
||||
_db.HashSet(redisKey, new HashEntry[] {
|
||||
new HashEntry("old", Math.Clamp(updRecord.OldWeight, 0, 100)),
|
||||
new HashEntry("new", Math.Clamp(updRecord.NewWeight, 0, 100))
|
||||
});
|
||||
|
||||
// 2. 🚀 COORDINAZIONE: Rimuovi la chiave da FusionCache.
|
||||
// Grazie al Backplane Pub/Sub, la RAM verrà azzerata istantaneamente su TUTTI i server.
|
||||
var cacheKey = $"weights:{updRecord.Method}";
|
||||
_cache.Remove(cacheKey);
|
||||
|
||||
return true;
|
||||
|
||||
#if false
|
||||
var key = _keyPrefix + updRecord.Method;
|
||||
_db.HashSet(key, new HashEntry[] {
|
||||
new HashEntry("old", Math.Clamp(updRecord.OldWeight, 0, 100)),
|
||||
new HashEntry("new", Math.Clamp(updRecord.NewWeight, 0, 100))
|
||||
});
|
||||
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
||||
#endregion Public Methods
|
||||
|
||||
#region Private Fields
|
||||
|
||||
private static string _keyPrefix = "route_weight:";
|
||||
private static string _redisBaseKey = "";
|
||||
private readonly IFusionCache _cache;
|
||||
|
||||
/// <summary>
|
||||
/// Definizione Record leggero per la cache
|
||||
/// </summary>
|
||||
/// <param name="OldWeight"></param>
|
||||
/// <param name="NewWeight"></param>
|
||||
public record RouteWeights(int OldWeight, int NewWeight);
|
||||
private readonly IConfiguration _config;
|
||||
|
||||
private readonly IDatabase _db;
|
||||
|
||||
private readonly int _defaultNew;
|
||||
|
||||
private readonly int _defaultOld;
|
||||
|
||||
private readonly IConnectionMultiplexer _mux;
|
||||
|
||||
#endregion Private Fields
|
||||
|
||||
#region Private Methods
|
||||
|
||||
private string KeyToString(string key)
|
||||
{
|
||||
if (string.IsNullOrEmpty(key)) return "";
|
||||
@@ -140,18 +247,6 @@ namespace MP.RIOC.Services
|
||||
return key;
|
||||
}
|
||||
|
||||
#endregion Public Methods
|
||||
|
||||
#region Private Fields
|
||||
|
||||
private static string _keyPrefix = "route_weight:";
|
||||
private static string _redisBaseKey = "";
|
||||
private readonly IConfiguration _config;
|
||||
private readonly IDatabase _db;
|
||||
private readonly IConnectionMultiplexer _mux;
|
||||
private readonly int _defaultNew;
|
||||
private readonly int _defaultOld;
|
||||
|
||||
#endregion Private Fields
|
||||
#endregion Private Methods
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,8 @@
|
||||
"LogLevel": {
|
||||
"Default": "Information",
|
||||
"Yarp": "Warning",
|
||||
"Microsoft.AspNetCore": "Warning"
|
||||
"Microsoft.AspNetCore": "Warning",
|
||||
"FusionCache": "Warning"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,8 @@
|
||||
"LogLevel": {
|
||||
"Default": "Information",
|
||||
"Yarp": "Warning",
|
||||
"Microsoft.AspNetCore": "Warning"
|
||||
"Microsoft.AspNetCore": "Warning",
|
||||
"FusionCache": "Warning"
|
||||
}
|
||||
},
|
||||
"AllowedHosts": "*",
|
||||
|
||||
@@ -5,11 +5,17 @@
|
||||
"Yarp": "Warning",
|
||||
"Microsoft": "Warning",
|
||||
"Microsoft.AspNetCore": "Warning",
|
||||
"Microsoft.AspNetCore.Hosting.Diagnostics": "Warning"
|
||||
"Microsoft.AspNetCore.Hosting.Diagnostics": "Warning",
|
||||
"FusionCache": "Warning"
|
||||
}
|
||||
},
|
||||
"NLog": {
|
||||
"rules": [
|
||||
{
|
||||
"logger": "FusionCache",
|
||||
"maxLevel": "Info",
|
||||
"final": true
|
||||
},
|
||||
{
|
||||
"logger": "Microsoft.*",
|
||||
"maxLevel": "Fatal",
|
||||
|
||||
@@ -4,7 +4,8 @@
|
||||
"Default": "Warning",
|
||||
"Yarp": "Warning",
|
||||
"Microsoft.EntityFrameworkCore": "Warning",
|
||||
"Microsoft.AspNetCore.Hosting.Diagnostics": "Information"
|
||||
"Microsoft.AspNetCore.Hosting.Diagnostics": "Information",
|
||||
"FusionCache": "Warning"
|
||||
}
|
||||
},
|
||||
"NLog": {
|
||||
|
||||
@@ -5,11 +5,17 @@
|
||||
"Yarp": "Warning",
|
||||
"Microsoft": "Warning",
|
||||
"Microsoft.AspNetCore": "Warning",
|
||||
"Microsoft.AspNetCore.Hosting.Diagnostics": "Warning"
|
||||
"Microsoft.AspNetCore.Hosting.Diagnostics": "Warning",
|
||||
"FusionCache": "Warning"
|
||||
}
|
||||
},
|
||||
"NLog": {
|
||||
"rules": [
|
||||
{
|
||||
"logger": "FusionCache",
|
||||
"maxLevel": "Info",
|
||||
"final": true
|
||||
},
|
||||
{
|
||||
"logger": "Microsoft.*",
|
||||
"maxLevel": "Fatal",
|
||||
|
||||
@@ -6,7 +6,8 @@
|
||||
"Microsoft.AspNetCore.Hosting.Diagnostics": "Information",
|
||||
"Microsoft.EntityFrameworkCore.Database.Command": "Warning",
|
||||
"Microsoft.EntityFrameworkCore": "Warning",
|
||||
"Microsoft.AspNetCore": "Warning"
|
||||
"Microsoft.AspNetCore": "Warning",
|
||||
"FusionCache": "Warning"
|
||||
}
|
||||
},
|
||||
"AllowedHosts": "*",
|
||||
@@ -40,6 +41,11 @@
|
||||
}
|
||||
},
|
||||
"rules": [
|
||||
{
|
||||
"logger": "FusionCache*",
|
||||
"maxLevel": "Info",
|
||||
"final": true
|
||||
},
|
||||
{
|
||||
"logger": "Microsoft.EntityFrameworkCore.*",
|
||||
"maxLevel": "Info",
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<RootNamespace>MP.SPEC</RootNamespace>
|
||||
<Version>8.16.2606.1312</Version>
|
||||
<Version>8.16.2606.2012</Version>
|
||||
<UserSecretsId>1800a78a-6ff1-40f9-b490-87fb8bfc1394</UserSecretsId>
|
||||
<SatelliteResourceLanguages>en</SatelliteResourceLanguages>
|
||||
</PropertyGroup>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<body>
|
||||
<i>Modulo MAPOSPEC </i>
|
||||
<h4>Versione: 8.16.2606.1312</h4>
|
||||
<h4>Versione: 8.16.2606.2012</h4>
|
||||
<br /> Note di rilascio:
|
||||
<ul>
|
||||
<li>
|
||||
|
||||
@@ -1 +1 @@
|
||||
8.16.2606.1312
|
||||
8.16.2606.2012
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<item>
|
||||
<version>8.16.2606.1312</version>
|
||||
<version>8.16.2606.2012</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>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<RootNamespace>MP.Stats</RootNamespace>
|
||||
<UserSecretsId>826e877c-ba70-4253-84cb-d0b1cafd4440</UserSecretsId>
|
||||
<Version>8.16.2606.1312</Version>
|
||||
<Version>8.16.2606.2012</Version>
|
||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||
<SatelliteResourceLanguages>en</SatelliteResourceLanguages>
|
||||
</PropertyGroup>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<body>
|
||||
<i>Modulo statistiche MAPO</i>
|
||||
<h4>Versione: 8.16.2606.1312</h4>
|
||||
<h4>Versione: 8.16.2606.2012</h4>
|
||||
<br />
|
||||
Note di rilascio:
|
||||
<ul>
|
||||
|
||||
@@ -1 +1 @@
|
||||
8.16.2606.1312
|
||||
8.16.2606.2012
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<item>
|
||||
<version>8.16.2606.1312</version>
|
||||
<version>8.16.2606.2012</version>
|
||||
<url>https://nexus.steamware.net/repository/SWS/MP-STATS/stable/LAST/MP.Stats.zip</url>
|
||||
<changelog>https://nexus.steamware.net/repository/SWS/MP-STATS/stable/LAST/ChangeLog.html</changelog>
|
||||
<mandatory>false</mandatory>
|
||||
|
||||
Reference in New Issue
Block a user