From 5b6ccd560d2687ead3e42860a4e3aee3997d08f2 Mon Sep 17 00:00:00 2001 From: Samuele Locatelli Date: Wed, 19 Apr 2023 11:15:37 +0200 Subject: [PATCH] WDC.UI: - spostato servizi da WDCDataService a servizio in Data - inizio modifica comportamento invio richieste calcolo e risposte --- .../Services/QueueDataService.cs | 142 ++++++++++++++- .../Buttons/ButtonsDoorDef.razor.cs | 5 +- .../DoorDef/DoorDefSizingSI.razor.cs | 3 +- .../DoorDef/DoorSizingStep.razor.cs | 7 +- .../Hardware/HwSingleInstance.razor.cs | 3 +- WebDoorCreator.UI/Data/WDCCurrDataService.cs | 167 ------------------ .../Pages/DoorDefinition.razor.cs | 3 +- WebDoorCreator.UI/Program.cs | 6 +- 8 files changed, 156 insertions(+), 180 deletions(-) delete mode 100644 WebDoorCreator.UI/Data/WDCCurrDataService.cs diff --git a/WebDoorCreator.Data/Services/QueueDataService.cs b/WebDoorCreator.Data/Services/QueueDataService.cs index fbec85f..7d02282 100644 --- a/WebDoorCreator.Data/Services/QueueDataService.cs +++ b/WebDoorCreator.Data/Services/QueueDataService.cs @@ -5,6 +5,7 @@ using NLog; using StackExchange.Redis; using System.Diagnostics; using WebDoorCreator.Core; +using WebDoorCreator.Data; using WebDoorCreator.Data.DbModels; namespace WebDoorCreator.API.Data @@ -13,10 +14,12 @@ namespace WebDoorCreator.API.Data { #region Public Fields +#if false /// /// Classe Accesso metodi DB /// - public static WebDoorCreator.Data.Controllers.WebDoorCreatorController dbController = null!; + public static WebDoorCreator.Data.Controllers.WebDoorCreatorController dbController = null!; +#endif #endregion Public Fields @@ -44,7 +47,10 @@ namespace WebDoorCreator.API.Data this.redisConn = ConnectionMultiplexer.Connect(redConnString); this.redisDb = this.redisConn.GetDatabase(); } - + // setup canali pub/sub + calcReqPipe = new MessagePipe(redisConn, Constants.CALC_REQ_QUEUE); + calcDonePipe = new MessagePipe(redisConn, Constants.CALC_DONE_QUEUE); +#if false // Conf DB var connStrDB = _configuration.GetConnectionString("WDC.DB"); if (string.IsNullOrEmpty(connStrDB)) @@ -55,19 +61,35 @@ namespace WebDoorCreator.API.Data { dbController = new WebDoorCreator.Data.Controllers.WebDoorCreatorController(configuration); Log.Info("DbController OK"); - } + } +#endif } #endregion Public Constructors + + /// + /// Message pipe esecuzione elaborazione CAM --> UI + /// + public MessagePipe calcDonePipe { get; set; } = null!; + + /// + /// Message pipe richieste elaborazione UI --> CAM + /// + public MessagePipe calcReqPipe { get; set; } = null!; + #region Public Methods public void Dispose() { + redisConn.Dispose(); +#if false // Clear database controller - dbController.Dispose(); + dbController.Dispose(); +#endif } +#if false /// /// Doors list by orderId /// @@ -107,7 +129,70 @@ namespace WebDoorCreator.API.Data TimeSpan ts = stopWatch.Elapsed; Log.Debug($"DoorGetByOrderId | {source} in: {ts.TotalMilliseconds} ms"); return dbResult; + } +#endif + public async Task FlushRedisCache() + { + await Task.Delay(1); + RedisValue pattern = new RedisValue($"{Constants.BASE_HASH}:Cache*"); + bool answ = await ExecFlushRedisPattern(pattern); + return answ; } + /// + /// Esegue flush memoria redis dato pattern + /// + /// + /// + private async Task ExecFlushRedisPattern(RedisValue pattern) + { + bool answ = false; + var listEndpoints = redisConn.GetEndPoints(); + foreach (var endPoint in listEndpoints) + { + //var server = redisConnAdmin.GetServer(listEndpoints[0]); + var server = redisConn.GetServer(endPoint); + if (server != null) + { + var keyList = server.Keys(redisDb.Database, pattern); + foreach (var item in keyList) + { + await redisDb.KeyDeleteAsync(item); + } + // brutalmente rimuovo intero contenuto DB... DANGER + //await server.FlushDatabaseAsync(); + answ = true; + } + } + + return answ; + } + public async Task sendCalcReq(string message) + { + // accumulo richieste di calcolo in HashTable redis + + // to do + + // invio sul channel redis la richiesta, salvando il valore anche in cache + bool answ = calcReqPipe.saveAndSendMessage(Constants.LAST_CALC_REQ_KEY, message); + + // simulazione ritorno dati... + await Task.Delay(200); + + // invio il FINTO messaggio di ritorno... + string retMess = ""; + string fileName = Path.Combine("temp", $"Logo{idxSim:00}.svg"); + if (File.Exists(fileName)) + { + retMess = File.ReadAllText(fileName); + idxSim++; + idxSim = idxSim % 4; + } + calcDonePipe.saveAndSendMessage(Constants.LAST_CALC_DONE_KEY, retMess); + + return answ; + } + + protected int idxSim = 0; /// /// Get # of calculation request pending @@ -231,6 +316,55 @@ namespace WebDoorCreator.API.Data return dictResult; } + /// + /// Enqueue DDF processing req from UI + /// + /// + /// Contenuto completo del DDF + /// Version / iteration on DDF processing request + public async Task EnqueueDoorDDF(int DoorId, string FullDDF) + { + // ragiono sulla tab di PENDING REQ + string source = "REDIS"; + int currVers = 0; + Stopwatch stopWatch = new Stopwatch(); + stopWatch.Start(); + + // per prima cosa controllo se ho GIA' in coda qualcosa come richeiste + var numPending = await NumRequestPending(); + // se coda vuota --> aggiungo e stop + if (numPending == 0) + { + } + // se coda non vuota: cerco la DoorId corrente, se c'è sovrascrivo versione altrimenti inserisco in coda + else + { + + } + // salvo nell'archivio REDIS delle porte il DDF corrente (door+ vers numb), potrebbe venire buono anche x eventuale UNDO... + + // invio sul canale dei messaggi il numero di items in coda attuali x chiedere esecuzione... + + +#if false + // cerco da cache + RedisKey currKey = new RedisKey(Constants.CALC_REQ_PEND); + currVers = redisDb.HashLength(currKey); + if (currVers > 0) + { + var rawData = await redisDb.HashGetAllAsync(currKey); + foreach (var item in rawData) + { + dictResult.Add($"{item.Name}", $"{item.Value}"); + } + } +#endif + stopWatch.Stop(); + TimeSpan ts = stopWatch.Elapsed; + Log.Debug($"EnqueueDoorDDF | DoorId: {DoorId} enqueued in: {ts.TotalMilliseconds} ms"); + return currVers; + } + #endregion Public Methods #region Protected Fields diff --git a/WebDoorCreator.UI/Components/Buttons/ButtonsDoorDef.razor.cs b/WebDoorCreator.UI/Components/Buttons/ButtonsDoorDef.razor.cs index 67455ee..6991b90 100644 --- a/WebDoorCreator.UI/Components/Buttons/ButtonsDoorDef.razor.cs +++ b/WebDoorCreator.UI/Components/Buttons/ButtonsDoorDef.razor.cs @@ -1,6 +1,7 @@ using Microsoft.AspNetCore.Components; using Microsoft.JSInterop; using Newtonsoft.Json; +using WebDoorCreator.API.Data; using WebDoorCreator.Data.DbModels; using WebDoorCreator.Data.DTO; using WebDoorCreator.UI.Data; @@ -28,7 +29,7 @@ namespace WebDoorCreator.UI.Components.Buttons protected WebDoorCreatorService WDCService { get; set; } = null!; [Inject] - protected WDCCurrDataService CamDataServ { get; set; } = null!; + protected QueueDataService QueueDataServ { get; set; } = null!; [Inject] @@ -128,7 +129,7 @@ namespace WebDoorCreator.UI.Components.Buttons await SaveYaml(); } - await CamDataServ.sendCalcReq($"ORD{idOrd:00000}"); + await QueueDataServ.sendCalcReq($"ORD{idOrd:00000}"); } } } \ No newline at end of file diff --git a/WebDoorCreator.UI/Components/DoorDef/DoorDefSizingSI.razor.cs b/WebDoorCreator.UI/Components/DoorDef/DoorDefSizingSI.razor.cs index 2ca4f88..611e0b7 100644 --- a/WebDoorCreator.UI/Components/DoorDef/DoorDefSizingSI.razor.cs +++ b/WebDoorCreator.UI/Components/DoorDef/DoorDefSizingSI.razor.cs @@ -1,6 +1,7 @@ using Microsoft.AspNetCore.Components; using Microsoft.JSInterop; using Newtonsoft.Json; +using WebDoorCreator.API.Data; using WebDoorCreator.Data.DbModels; using WebDoorCreator.UI.Data; @@ -80,7 +81,7 @@ namespace WebDoorCreator.UI.Components.DoorDef protected WDCVocabularyService WDVService { get; set; } = null!; [Inject] - protected WDCCurrDataService CamDataServ { get; set; } = null!; + protected QueueDataService CamDataServ { get; set; } = null!; #endregion Protected Properties diff --git a/WebDoorCreator.UI/Components/DoorDef/DoorSizingStep.razor.cs b/WebDoorCreator.UI/Components/DoorDef/DoorSizingStep.razor.cs index 01823c8..e11ff84 100644 --- a/WebDoorCreator.UI/Components/DoorDef/DoorSizingStep.razor.cs +++ b/WebDoorCreator.UI/Components/DoorDef/DoorSizingStep.razor.cs @@ -1,5 +1,6 @@ using Microsoft.AspNetCore.Components; using Newtonsoft.Json; +using WebDoorCreator.API.Data; using WebDoorCreator.Data.DbModels; using WebDoorCreator.UI.Data; @@ -11,7 +12,7 @@ namespace WebDoorCreator.UI.Components.DoorDef protected WebDoorCreatorService WDService { get; set; } = null!; [Inject] - protected WDCCurrDataService CamDataServ { get; set; } = null!; + protected QueueDataService CamDataServ { get; set; } = null!; [Parameter] public int DoorId { get; set; } = 0; @@ -80,7 +81,7 @@ namespace WebDoorCreator.UI.Components.DoorDef // if (_lockEdge != DefaultEdges.lockEdge) // { // paramIsChanged = true; - // var pUpd = Task.Run(async () => await CamDataServ.sendCalcReq($"ORD{DoorId:00000}")); + // var pUpd = Task.Run(async () => await QueueDataServ.sendCalcReq($"ORD{DoorId:00000}")); // } // } // } @@ -99,7 +100,7 @@ namespace WebDoorCreator.UI.Components.DoorDef // if (_height != DefaultSizing.height) // { // paramIsChanged = true; - // var pUpd = Task.Run(async () => await CamDataServ.sendCalcReq($"ORD{DoorId:00000}")); + // var pUpd = Task.Run(async () => await QueueDataServ.sendCalcReq($"ORD{DoorId:00000}")); // } // } // } diff --git a/WebDoorCreator.UI/Components/Hardware/HwSingleInstance.razor.cs b/WebDoorCreator.UI/Components/Hardware/HwSingleInstance.razor.cs index 68f7ff0..ffd3bf0 100644 --- a/WebDoorCreator.UI/Components/Hardware/HwSingleInstance.razor.cs +++ b/WebDoorCreator.UI/Components/Hardware/HwSingleInstance.razor.cs @@ -1,6 +1,7 @@ using Microsoft.AspNetCore.Components; using Microsoft.JSInterop; using Newtonsoft.Json; +using WebDoorCreator.API.Data; using WebDoorCreator.Data.DbModels; using WebDoorCreator.UI.Data; @@ -110,7 +111,7 @@ namespace WebDoorCreator.UI.Components.Hardware protected WDCVocabularyService WDVService { get; set; } = null!; [Inject] - protected WDCCurrDataService CamDataServ { get; set; } = null!; + protected QueueDataService CamDataServ { get; set; } = null!; #endregion Protected Properties diff --git a/WebDoorCreator.UI/Data/WDCCurrDataService.cs b/WebDoorCreator.UI/Data/WDCCurrDataService.cs deleted file mode 100644 index 8f98220..0000000 --- a/WebDoorCreator.UI/Data/WDCCurrDataService.cs +++ /dev/null @@ -1,167 +0,0 @@ -using NLog; -using StackExchange.Redis; -using WebDoorCreator.Core; -using WebDoorCreator.Data; - -namespace WebDoorCreator.UI.Data -{ - public class WDCCurrDataService : IDisposable - { - #region Public Constructors - - public WDCCurrDataService(IConfiguration configuration, IConnectionMultiplexer redisConn) - { - _configuration = configuration; - - // setup compoenti REDIS - this.redisConn = ConnectionMultiplexer.Connect(_configuration.GetConnectionString("Redis")); - this.redisDb = this.redisConn.GetDatabase(); - // setup canali pub/sub - calcReqPipe = new MessagePipe(redisConn, Constants.CALC_REQ_QUEUE); - calcDonePipe = new MessagePipe(redisConn, Constants.CALC_DONE_QUEUE); - } - - #endregion Public Constructors - - #region Public Properties - - /// - /// Message pipe esecuzione elaborazione CAM --> UI - /// - public MessagePipe calcDonePipe { get; set; } = null!; - - /// - /// Message pipe richieste elaborazione UI --> CAM - /// - public MessagePipe calcReqPipe { get; set; } = null!; - - #endregion Public Properties - - #region Public Methods - - public void Dispose() - { - redisConn.Dispose(); - } - - public async Task FlushRedisCache() - { - await Task.Delay(1); - RedisValue pattern = new RedisValue($"{Constants.BASE_HASH}:Cache*"); - bool answ = await ExecFlushRedisPattern(pattern); - return answ; - } - - public async Task sendCalcReq(string message) - { - // accumulo richieste di calcolo in HashTable redis - - // to do - - // invio sul channel redis la richiesta, salvando il valore anche in cache - bool answ = calcReqPipe.saveAndSendMessage(Constants.LAST_CALC_REQ_KEY, message); - - // simulazione ritorno dati... - await Task.Delay(200); - - // invio il FINTO messaggio di ritorno... - string retMess = ""; - string fileName = Path.Combine("temp", $"Logo{idxSim:00}.svg"); - if (File.Exists(fileName)) - { - retMess = File.ReadAllText(fileName); - idxSim++; - idxSim = idxSim % 4; - } - calcDonePipe.saveAndSendMessage(Constants.LAST_CALC_DONE_KEY, retMess); - - return answ; - } - - #endregion Public Methods - - #region Protected Fields - - protected int idxSim = 0; - - #endregion Protected Fields - - #region Private Fields - - private static IConfiguration _configuration = null!; - private static Logger Log = LogManager.GetCurrentClassLogger(); -#if false - /// - /// Conf allarmi (BankBit) IMPOSTATA con valori silenziati - /// - /// - public async Task> getAlarmBankBitSetup() - { - List? redResult = new List(); - string rawData = await redisDb.StringGetAsync(Constants.ALARMS_SETT_BBIT_KEY); - //se non avessi trovato valori cerco quelli di setup... - if (string.IsNullOrEmpty(rawData)) - { - rawData = await redisDb.StringGetAsync(Constants.ALARMS_CONF_KEY); - } - // ora provo a deserializzare - if (!string.IsNullOrEmpty(rawData)) - { - redResult = JsonConvert.DeserializeObject>(rawData); - } - // altrimenti imposto vuoto - if (redResult == null) - { - redResult = new List(); - } - return await Task.FromResult(redResult); - } -#endif - - /// - /// Oggetto per connessione a REDIS - /// - private ConnectionMultiplexer redisConn = null!; - - //ISubscriber sub = redis.GetSubscriber(); - /// - /// Oggetto DB redis da impiegare x chiamate R/W - /// - private IDatabase redisDb = null!; - - #endregion Private Fields - - #region Private Methods - - /// - /// Esegue flush memoria redis dato pattern - /// - /// - /// - private async Task ExecFlushRedisPattern(RedisValue pattern) - { - bool answ = false; - var listEndpoints = redisConn.GetEndPoints(); - foreach (var endPoint in listEndpoints) - { - //var server = redisConnAdmin.GetServer(listEndpoints[0]); - var server = redisConn.GetServer(endPoint); - if (server != null) - { - var keyList = server.Keys(redisDb.Database, pattern); - foreach (var item in keyList) - { - await redisDb.KeyDeleteAsync(item); - } - // brutalmente rimuovo intero contenuto DB... DANGER - //await server.FlushDatabaseAsync(); - answ = true; - } - } - - return answ; - } - - #endregion Private Methods - } -} \ No newline at end of file diff --git a/WebDoorCreator.UI/Pages/DoorDefinition.razor.cs b/WebDoorCreator.UI/Pages/DoorDefinition.razor.cs index 22cfade..24cbd86 100644 --- a/WebDoorCreator.UI/Pages/DoorDefinition.razor.cs +++ b/WebDoorCreator.UI/Pages/DoorDefinition.razor.cs @@ -2,6 +2,7 @@ using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.WebUtilities; using Microsoft.JSInterop; using NLog; +using WebDoorCreator.API.Data; using WebDoorCreator.Data; using WebDoorCreator.Data.DbModels; using WebDoorCreator.UI.Data; @@ -23,7 +24,7 @@ namespace WebDoorCreator.UI.Pages #region Protected Properties [Inject] - protected WDCCurrDataService CamDataServ { get; set; } = null!; + protected QueueDataService CamDataServ { get; set; } = null!; protected string DoorSvgContent { get; set; } = ""; protected int idDoor { get; set; } = 0; diff --git a/WebDoorCreator.UI/Program.cs b/WebDoorCreator.UI/Program.cs index f261c06..e5320eb 100644 --- a/WebDoorCreator.UI/Program.cs +++ b/WebDoorCreator.UI/Program.cs @@ -10,6 +10,7 @@ using Microsoft.AspNetCore.Localization; using Microsoft.EntityFrameworkCore; using StackExchange.Redis; using System.Globalization; +using WebDoorCreator.API.Data; using WebDoorCreator.Data; using WebDoorCreator.UI.Areas.Identity; using WebDoorCreator.UI.Data; @@ -52,7 +53,10 @@ builder.Services.AddServerSideBlazor(); builder.Services.AddSingleton(); builder.Services.AddScoped(); builder.Services.AddSingleton(); -builder.Services.AddSingleton(); +#if false +builder.Services.AddSingleton(); +#endif +builder.Services.AddSingleton(); builder.Services.AddScoped>(); builder.Services.AddHttpContextAccessor(); builder.Services.AddSingleton(redisMultiplexer);