Inizio fix controller con deduplica INIT componenti REDIS (& co...)
This commit is contained in:
@@ -18,14 +18,21 @@ namespace Lux.API.Controllers
|
||||
{
|
||||
#region Public Constructors
|
||||
|
||||
public WindowController(IConfiguration config, ILogger<WindowController> logger, ImageCacheService imgServ, ExecProcessManager? EgwProcManager = null)
|
||||
public WindowController(IConfiguration config,
|
||||
ILogger<WindowController> logger,
|
||||
ImageCacheService imgServ,
|
||||
IConnectionMultiplexer redisConn)
|
||||
//ExecProcessManager? EgwProcManager = null)
|
||||
{
|
||||
_logger = logger;
|
||||
_config = config;
|
||||
|
||||
// setup compoenti REDIS
|
||||
redisConn = ConnectionMultiplexer.Connect(_config.GetConnectionString("Redis") ?? "localhost");
|
||||
// setup REDIS da DI
|
||||
#if false
|
||||
redisConn = ConnectionMultiplexer.Connect(_config.GetConnectionString("Redis") ?? "localhost");
|
||||
#endif
|
||||
redisDb = redisConn.GetDatabase();
|
||||
_currSub = redisConn.GetSubscriber();
|
||||
|
||||
// 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()
|
||||
@@ -34,83 +41,24 @@ namespace Lux.API.Controllers
|
||||
};
|
||||
|
||||
// init classe sottoscrizione PubSub CHannel messages REDIS
|
||||
messageDisp.Subscribe(ChannelName("", true), (channel, message) =>
|
||||
_currSub.Subscribe(ChannelName("", true), (channel, message) =>
|
||||
{
|
||||
SaveCalcData(channel, message);
|
||||
});
|
||||
|
||||
#if false
|
||||
// verifico se usare engine
|
||||
enableEgwEng = _config.GetValue<bool>("ServerConf:EgwEngineEnab");
|
||||
#if false
|
||||
if (enableEgwEng && EgwProcManager != null)
|
||||
{
|
||||
ProcessMan = EgwProcManager;
|
||||
ProcessMan.m_AnswerReceived += ProcessMan_m_AnswerReceived;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
ImgService = imgServ;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Demorichiesta jwd x fare test richiesta calcolo
|
||||
/// </summary>
|
||||
private string demoJwd = "{\r\n \"ProfilePath\": \"Profilo78\",\r\n \"AreaList\": [\r\n {\r\n \"Shape\": \"RECTANGLE\",\r\n \"DimensionList\": [\r\n {\r\n \"nIndex\": 1,\r\n \"sName\": \"Width\",\r\n \"dValue\": 1200.0\r\n },\r\n {\r\n \"nIndex\": 2,\r\n \"sName\": \"Height\",\r\n \"dValue\": 1500.0\r\n }\r\n ],\r\n \"JointList\": [\r\n {\r\n \"nIndex\": 1,\r\n \"JointType\": \"FULL_V\"\r\n },\r\n {\r\n \"nIndex\": 2,\r\n \"JointType\": \"FULL_V\"\r\n },\r\n {\r\n \"nIndex\": 3,\r\n \"JointType\": \"FULL_V\"\r\n },\r\n {\r\n \"nIndex\": 4,\r\n \"JointType\": \"FULL_V\"\r\n }\r\n ],\r\n \"BottomRail\": false,\r\n \"BottomRailQty\": 0,\r\n \"AreaList\": [\r\n {\r\n \"bIsSashVertical\": true,\r\n \"SashList\": [\r\n {\r\n \"OpeningType\": \"TURNONLY_LEFT\",\r\n \"bHasHandle\": false,\r\n \"dDimension\": 50.0\r\n },\r\n {\r\n \"OpeningType\": \"TILTTURN_RIGHT\",\r\n \"bHasHandle\": true,\r\n \"dDimension\": 50.0\r\n }\r\n ],\r\n \"SashType\": \"NULL\",\r\n \"JointList\": [\r\n {\r\n \"nIndex\": 1,\r\n \"JointType\": \"FULL_V\"\r\n },\r\n {\r\n \"nIndex\": 2,\r\n \"JointType\": \"FULL_V\"\r\n },\r\n {\r\n \"nIndex\": 3,\r\n \"JointType\": \"FULL_V\"\r\n },\r\n {\r\n \"nIndex\": 4,\r\n \"JointType\": \"FULL_V\"\r\n }\r\n ],\r\n \"Hardware\": \"000000\",\r\n \"AreaList\": [\r\n {\r\n \"AreaList\": [\r\n {\r\n \"FillType\": \"GLASS\",\r\n \"AreaList\": [],\r\n \"AreaType\": \"FILL\"\r\n }\r\n ],\r\n \"AreaType\": \"SPLITTED\"\r\n },\r\n {\r\n \"AreaList\": [\r\n {\r\n \"FillType\": \"GLASS\",\r\n \"AreaList\": [],\r\n \"AreaType\": \"FILL\"\r\n }\r\n ],\r\n \"AreaType\": \"SPLITTED\"\r\n }\r\n ],\r\n \"AreaType\": \"SASH\"\r\n }\r\n ],\r\n \"AreaType\": \"FRAME\"\r\n }\r\n ]\r\n}";
|
||||
|
||||
/// <summary>
|
||||
/// Salva risultato calcolo da broadcast channel REDIS
|
||||
/// </summary>
|
||||
/// <param name="channel"></param>
|
||||
/// <param name="message"></param>
|
||||
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<ProcessArgsResult>(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}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Wrapper per invio messaggio richieste calcolo via REDIS
|
||||
/// </summary>
|
||||
/// <param name="notifyChannel"></param>
|
||||
/// <param name="message"></param>
|
||||
private void sendMessage(string notifyChannel, string message)
|
||||
{
|
||||
RedisChannel pubNotifyChannel = new RedisChannel(notifyChannel, RedisChannel.PatternMode.Literal);
|
||||
messageDisp.Publish(pubNotifyChannel, message);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Nome del channel sottoscritto per ritorno calcoli
|
||||
/// </summary>
|
||||
/// <param name="servId"></param>
|
||||
/// <returns></returns>
|
||||
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}";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Oggetto subscriber x pubblicazione/sottoscrizione canali REDIS
|
||||
/// </summary>
|
||||
private ISubscriber _currSub { get; set; } = null!;
|
||||
#if false
|
||||
/// <summary>
|
||||
/// Message Dispatcher: oggetto comunicazione pub/sub via REDIS channels corrente
|
||||
/// </summary>
|
||||
@@ -133,20 +81,8 @@ namespace Lux.API.Controllers
|
||||
// restituisco oggetto DB
|
||||
return answ;
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// conf speciale serializzatore JSON
|
||||
/// </summary>
|
||||
protected JsonSerializerSettings? JSSettings;
|
||||
|
||||
/// <summary>
|
||||
/// Oggetto per connessione a REDIS
|
||||
/// </summary>
|
||||
protected ConnectionMultiplexer redisConn = null!;
|
||||
/// <summary>
|
||||
/// Oggetto DB redis da impiegare x chiamate R/W
|
||||
/// </summary>
|
||||
protected IDatabase redisDb = null!;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endregion Public Constructors
|
||||
|
||||
@@ -172,7 +108,10 @@ namespace Lux.API.Controllers
|
||||
// ...se ricevo percorso --> leggo jwd/svg cablato
|
||||
if (!string.IsNullOrEmpty(currJwd))
|
||||
{
|
||||
#if false
|
||||
if (true || (enableEgwEng && ProcessMan != null))
|
||||
#endif
|
||||
if (true)
|
||||
{
|
||||
Dictionary<string, string> DictExec = new Dictionary<string, string>();
|
||||
DictExec.Add("Mode", "1");
|
||||
@@ -192,7 +131,7 @@ namespace Lux.API.Controllers
|
||||
{
|
||||
numWait--;
|
||||
await Task.Delay(waitDelay);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#if false
|
||||
@@ -206,7 +145,7 @@ namespace Lux.API.Controllers
|
||||
else
|
||||
{
|
||||
svgContent = "EMPTY";
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
sw.Stop();
|
||||
@@ -236,36 +175,131 @@ namespace Lux.API.Controllers
|
||||
return Ok(svgContent);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Chiamata POST: riceve Json in formato JWD serializzato, lo ripete come risposta
|
||||
/// PUT: api/calc/svg/00000000-0000-0000-0000-000000000000
|
||||
/// </summary>
|
||||
/// <param name="id">id oggetto</param>
|
||||
/// <returns></returns>
|
||||
[HttpGet("svgfile/{id}")]
|
||||
public ActionResult<string> svgFile(string id)
|
||||
{
|
||||
Stopwatch sw = new Stopwatch();
|
||||
sw.Start();
|
||||
|
||||
if (string.IsNullOrEmpty(id))
|
||||
return NotFound();
|
||||
|
||||
string svgContent = ImgService.LoadSvg(id);
|
||||
byte[] bytes = System.Text.Encoding.UTF8.GetBytes(svgContent);
|
||||
|
||||
sw.Stop();
|
||||
_logger.LogInformation($"svgString | {sw.Elapsed.TotalMilliseconds:N3} ms");
|
||||
|
||||
return File(bytes, "image/svg+xml");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Chiamata POST: riceve Json in formato JWD serializzato, lo ripete come risposta
|
||||
/// PUT: api/calc/svg/00000000-0000-0000-0000-000000000000
|
||||
/// </summary>
|
||||
/// <param name="id">id oggetto</param>
|
||||
/// <returns></returns>
|
||||
[HttpGet("svgfileasync/{id}")]
|
||||
public async Task<ActionResult<string>> svgFileAsync(string id)
|
||||
{
|
||||
Stopwatch sw = new Stopwatch();
|
||||
sw.Start();
|
||||
|
||||
if (string.IsNullOrEmpty(id))
|
||||
return NotFound();
|
||||
|
||||
string svgContent = await ImgService.LoadSvgAsync(id);
|
||||
byte[] bytes = System.Text.Encoding.UTF8.GetBytes(svgContent);
|
||||
|
||||
sw.Stop();
|
||||
_logger.LogInformation($"svgString | {sw.Elapsed.TotalMilliseconds:N3} ms");
|
||||
|
||||
return File(bytes, "image/svg+xml");
|
||||
}
|
||||
|
||||
#endregion Public Methods
|
||||
|
||||
#region Protected Fields
|
||||
|
||||
/// <summary>
|
||||
/// conf speciale serializzatore JSON
|
||||
/// </summary>
|
||||
protected JsonSerializerSettings? JSSettings;
|
||||
|
||||
/// <summary>
|
||||
/// Oggetto per connessione a REDIS
|
||||
/// </summary>
|
||||
protected ConnectionMultiplexer redisConn = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Oggetto DB redis da impiegare x chiamate R/W
|
||||
/// </summary>
|
||||
protected IDatabase redisDb = null!;
|
||||
|
||||
#endregion Protected Fields
|
||||
|
||||
#region Protected Properties
|
||||
|
||||
|
||||
|
||||
#endregion Protected Properties
|
||||
|
||||
#region Private Fields
|
||||
|
||||
private readonly ILogger<WindowController> _logger;
|
||||
|
||||
private IConfiguration _config;
|
||||
private bool enableEgwEng = true;
|
||||
|
||||
/// <summary>
|
||||
/// Demorichiesta jwd x fare test richiesta calcolo
|
||||
/// </summary>
|
||||
private string demoJwd = "{\r\n\"ProfilePath\":\"Profilo78\",\r\n\"AreaList\":[\r\n{\r\n\"Shape\":\"RECTANGLE\",\r\n\"DimensionList\":[\r\n{\r\n\"nIndex\":1,\r\n\"sName\":\"Width\",\r\n\"dValue\":1200.0\r\n},\r\n{\r\n\"nIndex\":2,\r\n\"sName\":\"Height\",\r\n\"dValue\":1500.0\r\n}\r\n],\r\n\"JointList\":[\r\n{\r\n\"nIndex\":1,\r\n\"JointType\":\"FULL_V\"\r\n},\r\n{\r\n\"nIndex\":2,\r\n\"JointType\":\"FULL_V\"\r\n},\r\n{\r\n\"nIndex\":3,\r\n\"JointType\":\"FULL_V\"\r\n},\r\n{\r\n\"nIndex\":4,\r\n\"JointType\":\"FULL_V\"\r\n}\r\n],\r\n\"BottomRail\":false,\r\n\"BottomRailQty\":0,\r\n\"AreaList\":[\r\n{\r\n\"bIsSashVertical\":true,\r\n\"SashList\":[\r\n{\r\n\"OpeningType\":\"TURNONLY_LEFT\",\r\n\"bHasHandle\":false,\r\n\"dDimension\":50.0\r\n},\r\n{\r\n\"OpeningType\":\"TILTTURN_RIGHT\",\r\n\"bHasHandle\":true,\r\n\"dDimension\":50.0\r\n}\r\n],\r\n\"SashType\":\"NULL\",\r\n\"JointList\":[\r\n{\r\n\"nIndex\":1,\r\n\"JointType\":\"FULL_V\"\r\n},\r\n{\r\n\"nIndex\":2,\r\n\"JointType\":\"FULL_V\"\r\n},\r\n{\r\n\"nIndex\":3,\r\n\"JointType\":\"FULL_V\"\r\n},\r\n{\r\n\"nIndex\":4,\r\n\"JointType\":\"FULL_V\"\r\n}\r\n],\r\n\"Hardware\":\"000000\",\r\n\"AreaList\":[\r\n{\r\n\"AreaList\":[\r\n{\r\n\"FillType\":\"GLASS\",\r\n\"AreaList\":[],\r\n\"AreaType\":\"FILL\"\r\n}\r\n],\r\n\"AreaType\":\"SPLITTED\"\r\n},\r\n{\r\n\"AreaList\":[\r\n{\r\n\"FillType\":\"GLASS\",\r\n\"AreaList\":[],\r\n\"AreaType\":\"FILL\"\r\n}\r\n],\r\n\"AreaType\":\"SPLITTED\"\r\n}\r\n],\r\n\"AreaType\":\"SASH\"\r\n}\r\n],\r\n\"AreaType\":\"FRAME\"\r\n}\r\n]\r\n}";
|
||||
|
||||
private bool enableEgwEng = false;
|
||||
|
||||
//private Dictionary<int, string> listSvg = new Dictionary<int, string>();
|
||||
private string lastSvg = "";
|
||||
|
||||
private int waitDelay = 10;
|
||||
|
||||
private bool waitResult = false;
|
||||
|
||||
#endregion Private Fields
|
||||
|
||||
#region Private Properties
|
||||
|
||||
/// <summary>
|
||||
/// Oggetto subscriber x pubblicazione/sottoscrizione canali REDIS
|
||||
/// </summary>
|
||||
private ISubscriber _currSub { get; set; } = null!;
|
||||
|
||||
private ImageCacheService ImgService { get; set; }
|
||||
|
||||
#endregion Private Properties
|
||||
|
||||
#if false
|
||||
/// <summary>
|
||||
/// Esecutore di processi generico
|
||||
/// </summary>
|
||||
private ExecProcessManager? ProcessMan { get; set; }
|
||||
|
||||
#endregion Private Properties
|
||||
#endif
|
||||
|
||||
#region Private Methods
|
||||
|
||||
/// <summary>
|
||||
/// Nome del channel sottoscritto per ritorno calcoli
|
||||
/// </summary>
|
||||
/// <param name="servId"></param>
|
||||
/// <returns></returns>
|
||||
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}";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Restituisce una risposta all'esecuzione
|
||||
/// </summary>
|
||||
@@ -282,11 +316,53 @@ namespace Lux.API.Controllers
|
||||
string newSvg = result.Args["Svg"];
|
||||
// salvo nel dizionario
|
||||
lastSvg = newSvg;
|
||||
// salvo su redis
|
||||
ImgService.SaveSvg("123456", lastSvg);
|
||||
#if false
|
||||
waitResult = false;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Salva risultato calcolo da broadcast channel REDIS
|
||||
/// </summary>
|
||||
/// <param name="channel"></param>
|
||||
/// <param name="message"></param>
|
||||
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<ProcessArgsResult>(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}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Wrapper per invio messaggio richieste calcolo via REDIS
|
||||
/// </summary>
|
||||
/// <param name="notifyChannel"></param>
|
||||
/// <param name="message"></param>
|
||||
private void sendMessage(string notifyChannel, string message)
|
||||
{
|
||||
RedisChannel pubNotifyChannel = new RedisChannel(notifyChannel, RedisChannel.PatternMode.Literal);
|
||||
_currSub.Publish(pubNotifyChannel, message);
|
||||
}
|
||||
|
||||
#endregion Private Methods
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user