Fix init RIOC, aggiunta fusioncache su RIOC, test con reset (da gestire meglio)
This commit is contained in:
+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 =>
|
||||
|
||||
Reference in New Issue
Block a user