From 367379542cc8b19d80e95847488d75ab23cb6381 Mon Sep 17 00:00:00 2001 From: Samuele Locatelli Date: Mon, 21 Jul 2025 16:49:54 +0200 Subject: [PATCH] Inizio modifica x passaggio richieste tramite REIDS channels pub/sub --- Lux.API/Controllers/WindowController.cs | 123 ++++++++++++++++++++++- Lux.API/ExtLib/EgwMultiEngineManager.dll | Bin 15360 -> 15360 bytes Lux.API/appsettings.Staging.json | 2 +- 3 files changed, 120 insertions(+), 5 deletions(-) diff --git a/Lux.API/Controllers/WindowController.cs b/Lux.API/Controllers/WindowController.cs index 2efe236e..a2faff0d 100644 --- a/Lux.API/Controllers/WindowController.cs +++ b/Lux.API/Controllers/WindowController.cs @@ -3,7 +3,11 @@ using Lux.Data; using Lux.Data.Services; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.Configuration; +using Newtonsoft.Json; +using StackExchange.Redis; using System.Diagnostics; +using System.Runtime; namespace Lux.API.Controllers { @@ -17,16 +21,119 @@ namespace Lux.API.Controllers { _logger = logger; _config = config; + + // setup compoenti REDIS + redisConn = ConnectionMultiplexer.Connect(_config.GetConnectionString("Redis") ?? "localhost"); + redisDb = redisConn.GetDatabase(); + + // json serializer... FIX errore loop circolare https://www.ryadel.com/en/jsonserializationexception-self-referencing-loop-detected-error-fix-entity-framework-asp-net-core/ + JSSettings = new JsonSerializerSettings() + { + ReferenceLoopHandling = ReferenceLoopHandling.Ignore + }; + + // init classe sottoscrizione PubSub CHannel messages REDIS + messageDisp.Subscribe(ChannelName("", true), (channel, message) => + { + SaveCalcData(channel, message); + }); + // verifico se usare engine enableEgwEng = _config.GetValue("ServerConf:EgwEngineEnab"); +#if false if (enableEgwEng && EgwProcManager != null) { ProcessMan = EgwProcManager; ProcessMan.m_AnswerReceived += ProcessMan_m_AnswerReceived; - } + } +#endif ImgService = imgServ; } + /// + /// Salva risultato calcolo da broadcast channel REDIS + /// + /// + /// + private void SaveCalcData(RedisChannel channel, RedisValue message) + { + string rawData = $"{message}"; + if (!string.IsNullOrEmpty(rawData) && rawData.Length > 2) + { + // provo a deserializzare + try + { + var retData = JsonConvert.DeserializeObject(rawData); + if (retData != null) + { + // verifico nId di risposta x salvare correttamente + ProcessMan_m_AnswerReceived(retData); + } + } + catch (Exception exc) + { + _logger.LogError($"Errore in fase decodifica messaggio da REDIS Channel{Environment.NewLine}{exc}"); + } + } + } + + private void sendMessage(string notifyChannel, string message) + { + RedisChannel pubNotifyChannel = new RedisChannel(notifyChannel, RedisChannel.PatternMode.Literal); + messageDisp.Publish(pubNotifyChannel, message); + } + + /// + /// Nome del channel sottoscritto per ritorno calcoli + /// + /// + /// + private string ChannelName(string servId, bool isOut) + { + return isOut ? $"EgwEngineOutput" : $"EgwEngineInput"; + // se implementassimo multi-elaborazione calcoli ogni esecutore ha un suo channel + //return $"EgwEngineOutput_{servId}"; + } + + /// + /// Oggetto subscriber x pubblicazione/sottoscrizione canali REDIS + /// + private ISubscriber _currSub { get; set; } = null!; + /// + /// Message Dispatcher: oggetto comunicazione pub/sub via REDIS channels corrente + /// + protected ISubscriber messageDisp + { + get + { + ISubscriber answ; + // se giĆ  valorizzato uso oggetto private... + if (_currSub != null) + { + answ = _currSub; + } + else + { + // sottoscrizione al dispatcher messaggi + answ = redisConn.GetSubscriber(); + _currSub = answ; + } + // restituisco oggetto DB + return answ; + } + } + + protected JsonSerializerSettings? JSSettings; + + /// + /// Oggetto per connessione a REDIS + /// + protected ConnectionMultiplexer redisConn = null!; + /// + /// Oggetto DB redis da impiegare x chiamate R/W + /// + protected IDatabase redisDb = null!; + #endregion Public Constructors #region Public Methods @@ -47,13 +154,18 @@ namespace Lux.API.Controllers // ...se ricevo percorso --> leggo jwd/svg cablato if (!string.IsNullOrEmpty(currJwd)) { - if (enableEgwEng && ProcessMan != null) + if (true || (enableEgwEng && ProcessMan != null)) { Dictionary DictExec = new Dictionary(); DictExec.Add("Mode", "1"); DictExec.Add("Jwd", currJwd); int nId = 1; ProcessArgs currArgs = new ProcessArgs(nId, DictExec); + + sendMessage(ChannelName("", false), currArgs.sProcessArgs); + svgContent = "DONE"; + +#if false bool done = ProcessMan.ArgumentsEnqueue(currArgs); waitResult = true; @@ -62,8 +174,10 @@ namespace Lux.API.Controllers { numWait--; await Task.Delay(waitDelay); - } + } +#endif } +#if false // se ho risultato mostro... if (!string.IsNullOrEmpty(lastSvg)) { @@ -74,7 +188,8 @@ namespace Lux.API.Controllers else { svgContent = "EMPTY"; - } + } +#endif } sw.Stop(); _logger.LogInformation($"svgString | {sw.Elapsed.TotalMilliseconds:N3} ms"); diff --git a/Lux.API/ExtLib/EgwMultiEngineManager.dll b/Lux.API/ExtLib/EgwMultiEngineManager.dll index 7276ed64a782164c0523870581ff4f0b284cc438..d5eeb1e766d9096a2ed9e3271794c052407f43a1 100644 GIT binary patch delta 255 zcmZpuXsDRb!P5H8chSZk4@pM0%~vJEMFlwLU(RFh-RQsd=WQJ=_f+f6Hu~#W?9$SV z6HN`%EK-sU%?vG5QcX;Zl1(j>lMIuLEX~u>k_^(4(^AY#jTjg>7#UE21N)V)lQm2N z1bU9`+9mRz#dYcf=SktkH$x|Pm~<*Y1zWE|1%awd|ENCxv$Sv7QIW_7#m$DM>MZ_g z3~3C;42cY;42D3K1w#r$GLU5k#FjvIDuW3S8Ue*jf&65KB%pW_kZ;Lg4pf~6WE%j< SWFSrf>M><7+PvH{k_iCWxlCIC delta 255 zcmZpuXsDRb!SY-B-KmW|9+HgAo3BcSiwY=f%u?cgb>4gNlHiURyS81}Y@@%9#m+J% z*~Bc#z|f9RNlPF!0%# P0Z?}$NbTn3mXS;VRsu=# diff --git a/Lux.API/appsettings.Staging.json b/Lux.API/appsettings.Staging.json index 3045c651..f44dfcf7 100644 --- a/Lux.API/appsettings.Staging.json +++ b/Lux.API/appsettings.Staging.json @@ -6,7 +6,7 @@ } }, "ServerConf": { - "EgwEngineEnab": false, + "EgwEngineEnab": true, "BaseUrl": "/Lux/srv/" } }