From f58580393d66b50cda7726effefd6dccb98e5c1c Mon Sep 17 00:00:00 2001 From: Samuele Locatelli Date: Mon, 19 Jan 2026 15:58:36 +0100 Subject: [PATCH] Update (da testare) x salvare task Run/Done --- .../Services/CalcRuidService.cs | 9 +- .../Services/ImageCacheService.cs | 2 +- EgwCoreLib.Lux.Data/Services/ProdService.cs | 116 ++++++++++++++++++ Lux.API/Controllers/ProdController.cs | 84 ------------- Lux.API/Lux.API.csproj | 2 +- Lux.API/Services/ExternalMessageProcessor.cs | 13 +- .../Components/Compo/WorkLoad/JobQueue.razor | 31 ++++- .../Compo/WorkLoad/JobQueueDisplay.razor | 37 ++---- .../Compo/WorkLoad/JobQueueDisplay.razor.cs | 26 +++- Lux.UI/Lux.UI.csproj | 2 +- Resources/ChangeLog.html | 2 +- Resources/VersNum.txt | 2 +- Resources/manifest.xml | 2 +- 13 files changed, 198 insertions(+), 130 deletions(-) diff --git a/EgwCoreLib.Lux.Data/Services/CalcRuidService.cs b/EgwCoreLib.Lux.Data/Services/CalcRuidService.cs index 60f7006e..b07e0a8c 100644 --- a/EgwCoreLib.Lux.Data/Services/CalcRuidService.cs +++ b/EgwCoreLib.Lux.Data/Services/CalcRuidService.cs @@ -302,15 +302,17 @@ namespace EgwCoreLib.Lux.Data.Services /// /// RUID richiesta /// - public async Task CompleteRequestAsync(string ruid) + public async Task CompleteRequestAsync(string ruid) { var hashKey = GetRequestKey(ruid); + string retVal = $"{hashKey}"; DateTime adesso = DateTime.Now; var processEnd = DateTimeOffset.Now.ToUnixTimeMilliseconds(); // Recupero processStart e altri dati var processStartValue = await _db.HashGetAsync(hashKey, "processStart"); - if (processStartValue.IsNull) return; + if (processStartValue.IsNull) + return retVal; var envir = await _db.HashGetAsync(hashKey, "envir"); var tipo = await _db.HashGetAsync(hashKey, "tipo"); @@ -400,6 +402,9 @@ namespace EgwCoreLib.Lux.Data.Services // Attendo completamento di tutti i task await Task.WhenAll(tasks); + + // restituisce hashKey trovata + return retVal; } /// diff --git a/EgwCoreLib.Lux.Data/Services/ImageCacheService.cs b/EgwCoreLib.Lux.Data/Services/ImageCacheService.cs index 19838d25..b22915ed 100644 --- a/EgwCoreLib.Lux.Data/Services/ImageCacheService.cs +++ b/EgwCoreLib.Lux.Data/Services/ImageCacheService.cs @@ -322,7 +322,7 @@ namespace EgwCoreLib.Lux.Data.Services /// /// /// - public async Task SaveProdEstimationAsync(string uid, EgwMultiEngineManager.Data.Constants.EXECENVIRONMENTS env, string estimContent) + public async Task SaveProdEstimateAsync(string uid, EgwMultiEngineManager.Data.Constants.EXECENVIRONMENTS env, string estimContent) { // salvo in cache string currKey = $"{redisBaseKey}:{env}:Estimation:{uid}"; diff --git a/EgwCoreLib.Lux.Data/Services/ProdService.cs b/EgwCoreLib.Lux.Data/Services/ProdService.cs index e44e4809..69aa7dcf 100644 --- a/EgwCoreLib.Lux.Data/Services/ProdService.cs +++ b/EgwCoreLib.Lux.Data/Services/ProdService.cs @@ -5,7 +5,10 @@ using Microsoft.Extensions.Configuration; using Newtonsoft.Json; using NLog; using StackExchange.Redis; +using System; +using System.Collections.Generic; using System.Diagnostics; +using static Egw.Window.Data.Enums; namespace EgwCoreLib.Lux.Data.Services { @@ -17,6 +20,7 @@ namespace EgwCoreLib.Lux.Data.Services { // conf redis service _redisService = redisService; + _db = redisConn.GetDatabase(); chPub = _config.GetValue("ServerConf:ChannelPub") ?? ""; queueCalcKey = (RedisKey)$"{redisBaseKey}:CalcQueue"; queueDoneKey = (RedisKey)$"{queueCalcKey}:Done"; @@ -28,6 +32,7 @@ namespace EgwCoreLib.Lux.Data.Services Log.Info($"ProdService | Init OK"); } + private readonly IDatabase _db; #endregion Public Constructors #region Public Enums @@ -131,6 +136,61 @@ namespace EgwCoreLib.Lux.Data.Services return result; } + /// + /// Verifica un job in una coda, se trovato lo "avanza" a fatto (per estimation/balance, ...) + /// + /// chiave da cercare x avanzarla + /// coda di default a run --> done + /// + public async Task SetDone(string key2adv, QueueType qType = QueueType.running) + { + Stopwatch sw = new Stopwatch(); + sw.Start(); + string reqUid = ""; + RedisKey rKey = qKey(qType); + // LPOS restituisce l'indice del valore nella lista + long? index = await _db.ListPositionAsync(rKey, "valore_da_cercare"); + + if (index.HasValue) + { + // Il valore esiste alla posizione index + var valore = await _db.ListGetByIndexAsync(rKey, index.Value); + reqUid = $"{valore}"; + // Il secondo parametro indica quante istanze eliminare: 0 = tutte, 1 = la prima dall'inizio, -1 = l'ultima dalla fine + long rimosse = await _db.ListRemoveAsync(rKey, "valore_da_cercare", 0); + // se tolte + if (rimosse > 0) + { + // inserisco in coda nuova! + _redisService.QueuePush(qKey(qType + 1), (RedisValue)reqUid); + } + } +#if false + // prendo dalla coda primo job (rimuovendolo...) + var rawReq = await _redisService.QueuePopAsync(rKey); + if (rawReq.HasValue) + { + string reqUid = $"{rawReq}"; + // metto UID in coda running nella successiva.. se non ultima... + if (qType < QueueType.running) + { + // FixMe ToDo !!!: salvataggio data-ora per indicare avvio calcolo... + _redisService.QueuePush(qKey(qType + 1), (RedisValue)reqUid); + } + // recupero richiesta serializzata + string currKey = $"{redisOrderReqKey}:{reqUid.Replace("/", ":")}"; + var rawRes = await _redisService.GetAsync(currKey); + if (!string.IsNullOrEmpty(rawRes)) + { + result = rawRes; + } + } +#endif + sw.Stop(); + Log.Info($"SetDone | queue: {rKey} | reqUid: {reqUid} | {sw.Elapsed.TotalMilliseconds:N3} ms"); + return reqUid; + } + /// /// Numero di Job in attesa su coda /// @@ -318,6 +378,62 @@ namespace EgwCoreLib.Lux.Data.Services return rKey; } + /// + /// Esegue avanzamento nella coda logica tra wait/run/done se possibile... + /// + /// Chiave hash del contenuto richiesta RUID + /// + public async Task UpdateQueue(string hashKey) + { + // recupero info accessorie da redis + var tipo = await _db.HashGetAsync(hashKey, "tipo"); + + // verifico SE si tratta di un create/estimate e nel caso processo coda req x sistemare + if (!tipo.IsNull && !string.IsNullOrEmpty(tipo)) + { + string rKey = ""; + var UID = await _db.HashGetAsync(hashKey, "UID"); + var parti = ((string)tipo).Split('-'); + if (parti.Length == 2) + { + if (parti[0] == "ORDER") + { + if (parti.Length == 2) + { + rKey = $"{parti[0]}:{parti[1]}:{UID}"; + } + } + // cerco solo tipo create / 5... + else if (parti[0] == "5") + { + if (int.TryParse(parti[0], out int iMode) && int.TryParse(parti[1], out int iSubMode)) + { + // Validazione e Cast in un colpo solo + bool modeValido = Enum.IsDefined(typeof(QuestionModes), iMode); + bool subModeValido = Enum.IsDefined(typeof(QuestionOrderSubModes), iSubMode); + + if (modeValido && subModeValido) + { + var cMode = (QuestionModes)iMode; + var cSubMode = (QuestionOrderSubModes)iSubMode; + rKey = $"{cMode}:{cSubMode}:{UID}"; + } + } + } + if (!string.IsNullOrEmpty(rKey)) + { + // cerco nella hash table RUN e nel caso sposto a DONE... + string cQueue = qKey(QueueType.running); + var hTask = await _db.HashGetAsync(cQueue, rKey); + if(hTask.HasValue ) + { + await SetDone($"{hTask}", QueueType.running); + } + } + } + } + } + #endregion Private Methods } } \ No newline at end of file diff --git a/Lux.API/Controllers/ProdController.cs b/Lux.API/Controllers/ProdController.cs index e4714462..149d2cc1 100644 --- a/Lux.API/Controllers/ProdController.cs +++ b/Lux.API/Controllers/ProdController.cs @@ -186,90 +186,6 @@ namespace Lux.API.Controllers } return Ok(rawData); } -#if false - - - /// - /// Ritorno calcolo - /// - /// Chiave auth valida (da implementare) - /// - /// - [HttpPost("jobreturn/{id}")] - public async Task JobReturn(string id, [FromBody] AnswerDTO retData) - { - bool saved = false; - // se risposta valida --> processo! - if (retData != null) - { - saved = await EMProc.ProcessAnswer(retData); -#if DEBUG - // se in debug forzo save dell'ultima chiamata comunque... - saved = false; -#endif - // se non avessi salvato e non sapessi cosa fosse --> salvo comunque x debug... - if (!saved && retData != null) - { - string UID = retData.Args["UID"]; - var envir = retData.ExecEnvironment; - // salvo in area generica... - string rawData = JsonConvert.SerializeObject(retData); - await EMProc.SaveRawData(UID, retData.ExecEnvironment, rawData); - } - } - // ritorno - return saved; - } - - - [HttpPost("jobcreate/{id}")] - public async Task JobCreate(string id, [FromBody] AnswerDTO retData) - { - bool saved = false; - // se risposta valida --> processo! - if (retData != null) - { - saved = await EMProc.ProcessAnswer(retData); - // se in debug forzo save dell'ultima chiamata comunque... - saved = false; - // se non avessi salvato e non sapessi cosa fosse --> salvo comunque x debug... - if (!saved && retData != null) - { - string UID = retData.Args["UID"]; - var envir = retData.ExecEnvironment; - // salvo in area generica... - string rawData = JsonConvert.SerializeObject(retData); - await EMProc.SaveRawData(UID, retData.ExecEnvironment, rawData); - } - } - // ritorno - return saved; - } - - [HttpPost("jobestimate/{id}")] - public async Task JobEstimate(string id, [FromBody] AnswerDTO retData) - { - bool saved = false; - // se risposta valida --> processo! - if (retData != null) - { - saved = await EMProc.ProcessAnswer(retData); - // se in debug forzo save dell'ultima chiamata comunque... - saved = false; - // se non avessi salvato e non sapessi cosa fosse --> salvo comunque x debug... - if (!saved && retData != null) - { - string UID = retData.Args["UID"]; - var envir = retData.ExecEnvironment; - // salvo in area generica... - string rawData = JsonConvert.SerializeObject(retData); - await EMProc.SaveRawData(UID, retData.ExecEnvironment, rawData); - } - } - // ritorno - return saved; - } -#endif /// /// Chiamata GET: num richieste in coda (se non specificato è waiting, altrimenti ) diff --git a/Lux.API/Lux.API.csproj b/Lux.API/Lux.API.csproj index c5751dc7..d1ade233 100644 --- a/Lux.API/Lux.API.csproj +++ b/Lux.API/Lux.API.csproj @@ -4,7 +4,7 @@ net8.0 enable enable - 0.9.2601.1910 + 0.9.2601.1915 diff --git a/Lux.API/Services/ExternalMessageProcessor.cs b/Lux.API/Services/ExternalMessageProcessor.cs index 06ebee7d..597a232f 100644 --- a/Lux.API/Services/ExternalMessageProcessor.cs +++ b/Lux.API/Services/ExternalMessageProcessor.cs @@ -18,14 +18,17 @@ namespace Lux.API.Services /// /// /// - public ExternalMessageProcessor(ImageCacheService imgService, DataLayerServices dlService, CalcRuidService crService) + public ExternalMessageProcessor(ImageCacheService imgService, DataLayerServices dlService, CalcRuidService crService, ProdService prodService) { cacheService = imgService; dbService = dlService; _calcRuidService = crService; + _prodService = prodService; } private readonly CalcRuidService _calcRuidService; + private readonly ProdService _prodService; + #endregion Public Constructors #region Public Methods @@ -106,7 +109,10 @@ namespace Lux.API.Services { RUID = retData.Args["RUID"]; // salvo SUBITO chiusura statistiche... - await _calcRuidService.CompleteRequestAsync(RUID); + string hKey = await _calcRuidService.CompleteRequestAsync(RUID); + + // verifico eventuali spostamenti code calcolo + await _prodService.UpdateQueue(hKey); } // gestione ritorno preview SVG @@ -172,7 +178,7 @@ namespace Lux.API.Services Log.Error($"Eccezione in gestione Estimate{Environment.NewLine}{exc}"); } // reinvio in redis (cache + channel) - await cacheService.SaveProdEstimationAsync(UID, retData.ExecEnvironment, rawAnsw); + await cacheService.SaveProdEstimateAsync(UID, retData.ExecEnvironment, rawAnsw); saved = true; } @@ -250,6 +256,7 @@ namespace Lux.API.Services return saved; } + /// /// Salvataggio della risposta in formato RawData x Debug /// diff --git a/Lux.UI/Components/Compo/WorkLoad/JobQueue.razor b/Lux.UI/Components/Compo/WorkLoad/JobQueue.razor index e56a4704..a5efde2a 100644 --- a/Lux.UI/Components/Compo/WorkLoad/JobQueue.razor +++ b/Lux.UI/Components/Compo/WorkLoad/JobQueue.razor @@ -1,18 +1,25 @@ 
    -
  1. +
  2. Coda Job @QueueType
    - @if (QueueAll.Count > 0 && EnableReset) + @if (QueueAll.Count > 0) {
    - + @if (EnableReset) + { + + } + else if (EnableClear) + { + + }
    }
  3. @if (QueuePaged == null || QueuePaged?.Count() == 0) { -
  4. Nessun Job Eseguito!
  5. +
  6. Nessun Job trovato!
  7. } else { @@ -24,7 +31,10 @@ @item
- + @if (EnableReRun) + { + + }
@@ -56,9 +66,18 @@ [Parameter] public string QueueType { get; set; } = "Run"; + [Parameter] + public string TitleCss { get; set; } = "bg-success"; + + [Parameter] + public bool EnableClear { get; set; } = false; + [Parameter] public bool EnableReset { get; set; } = false; + [Parameter] + public bool EnableReRun { get; set; } = false; + #endregion Public Properties #region Protected Methods @@ -103,7 +122,7 @@ /// /// elementi per pagina /// - private int numRecord = 10; + private int numRecord = 5; /// /// Numero tot records diff --git a/Lux.UI/Components/Compo/WorkLoad/JobQueueDisplay.razor b/Lux.UI/Components/Compo/WorkLoad/JobQueueDisplay.razor index 4c7cfe24..99499ad5 100644 --- a/Lux.UI/Components/Compo/WorkLoad/JobQueueDisplay.razor +++ b/Lux.UI/Components/Compo/WorkLoad/JobQueueDisplay.razor @@ -1,5 +1,5 @@ 
-
+ @*
  1. Job in Attesa
    @@ -25,20 +25,20 @@
    1. Job Eseguiti
      - @if (QueueRun.Count > 0) + @if (QueueDone.Count > 0) {
      }
    2. - @if (QueueRunPaged == null || QueueRunPaged?.Count() == 0) + @if (QueueDonePaged == null || QueueDonePaged?.Count() == 0) {
    3. Nessun Job Eseguito!
    4. } else { - foreach (var item in QueueRunPaged) + foreach (var item in QueueDonePaged) {
    5. @@ -59,29 +59,14 @@ } - @* *@ - +
      *@ +
      +
      - + +
      +
      +
\ No newline at end of file diff --git a/Lux.UI/Components/Compo/WorkLoad/JobQueueDisplay.razor.cs b/Lux.UI/Components/Compo/WorkLoad/JobQueueDisplay.razor.cs index f56f34df..90171c5c 100644 --- a/Lux.UI/Components/Compo/WorkLoad/JobQueueDisplay.razor.cs +++ b/Lux.UI/Components/Compo/WorkLoad/JobQueueDisplay.razor.cs @@ -82,7 +82,6 @@ namespace Lux.UI.Components.Compo.WorkLoad #region Private Properties - private IEnumerable? QueueRunPaged { get; set; } = null; private IEnumerable? QueueDonePaged { get; set; } = null; #endregion Private Properties @@ -95,12 +94,33 @@ namespace Lux.UI.Components.Compo.WorkLoad private void UpdateTable() { // fix paginazione - QueueRunPaged = QueueRun + QueueDonePaged = QueueDone .Skip(numRecord * (currPage - 1)) .Take(numRecord); - totalCount = QueueRun.Count(); + totalCount = QueueDone.Count(); } #endregion Private Methods + + /// + /// Esegue reset secondo tipo richiesta e coda + /// + /// + /// + private async Task ResetQueue(string qType) + { + // reset secondo richiesta... + switch (qType) + { + case "Waiting": + await ResetWaitQueue(); + break; + case "Running": + await ResetRunQueue(); + break; + default: + break; + } + } } } \ No newline at end of file diff --git a/Lux.UI/Lux.UI.csproj b/Lux.UI/Lux.UI.csproj index e259dda1..a9c1d234 100644 --- a/Lux.UI/Lux.UI.csproj +++ b/Lux.UI/Lux.UI.csproj @@ -5,7 +5,7 @@ enable enable aspnet-Lux.UI-a758c101-a2f4-4e38-977d-1c4887dbbd50 - 0.9.2601.1910 + 0.9.2601.1915 diff --git a/Resources/ChangeLog.html b/Resources/ChangeLog.html index 99c32b8c..6a1e60cd 100644 --- a/Resources/ChangeLog.html +++ b/Resources/ChangeLog.html @@ -1,6 +1,6 @@ LUX - Web Windows MES -

Versione: 0.9.2601.1910

+

Versione: 0.9.2601.1915


Note di rilascio:
  • diff --git a/Resources/VersNum.txt b/Resources/VersNum.txt index 5db554f2..aebe1931 100644 --- a/Resources/VersNum.txt +++ b/Resources/VersNum.txt @@ -1 +1 @@ -0.9.2601.1910 +0.9.2601.1915 diff --git a/Resources/manifest.xml b/Resources/manifest.xml index 45ce4b2f..5a44cf15 100644 --- a/Resources/manifest.xml +++ b/Resources/manifest.xml @@ -1,6 +1,6 @@ - 0.9.2601.1910 + 0.9.2601.1915 http://nexus.steamware.net/repository/SWS/GPW/stable/GPW.UI.zip http://nexus.steamware.net/repository/SWS/GPW/stable/ChangeLog.html false