using StackExchange.Redis; namespace MP.IOC.Services { public class RedisWeightProvider : IWeightProvider { #region Public Constructors public RedisWeightProvider(IConnectionMultiplexer mux, IConfiguration config) { _config = config; _db = mux.GetDatabase(); _defaultOld = config.GetValue("RouteMan:DefaultWeightOld", 100); _defaultNew = config.GetValue("RouteMan:DefaultWeightNew", 0); _redisBaseKey = config.GetValue("ServerConf:RedisBaseKey") ?? "MP_IOC"; _keyPrefix = $"{_redisBaseKey}:route_weight:"; } #endregion Public Constructors #region Public Methods /// /// Ritorna (oldWeight, newWeight) per il metodo. Se non esiste, crea la chiave con i default. /// public (int oldWeight, int newWeight) GetWeightsFor(string method) { if (string.IsNullOrEmpty(method)) method = "unknown"; 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); } // 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)) }); } #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 int _defaultNew; private readonly int _defaultOld; #endregion Private Fields } }