diff --git a/WebDoorCreator.API/Controllers/QueueController.cs b/WebDoorCreator.API/Controllers/QueueController.cs
index 3d52462..5359197 100644
--- a/WebDoorCreator.API/Controllers/QueueController.cs
+++ b/WebDoorCreator.API/Controllers/QueueController.cs
@@ -1,5 +1,6 @@
using Microsoft.AspNetCore.Mvc;
using NLog;
+using WebDoorCreator.Data.DTO;
using WebDoorCreator.Data.Services;
namespace WebDoorCreator.API.Controllers
@@ -20,8 +21,7 @@ namespace WebDoorCreator.API.Controllers
#endregion Public Constructors
- #region Public Methods
-
+#if false
///
/// Lunghezza coda in attesa
///
@@ -43,63 +43,39 @@ namespace WebDoorCreator.API.Controllers
long numQueue = await QDataServ.NumRequestProcessing();
return numQueue;
}
+#endif
+
+ #region Public Methods
///
- /// Invio elenco messaggi elaborazioni (se ho errori --> messaggi oppure libero)
+ /// Lunghezza coda in fase di processing
///
- ///
///
- [HttpPost("PostProcessingMessage")]
- public async Task PostProcessingMessage(Dictionary ProcMessageList)
+ [HttpGet("ActLenght")]
+ public async Task> ActLenght()
{
- bool answ = false;
- await Task.Delay(1);
+ Dictionary answ = new Dictionary();
+ var actPend = await QDataServ.NumRequestPending();
+ answ.Add("pending", actPend);
+
+ var actProc = await QDataServ.NumRequestProcessing();
+ answ.Add("processing", actProc);
return answ;
}
///
/// Invio elenco risultati elaborazioni (modalità boolean di esecuzione corretta)
///
- ///
+ /// Risultati elaborazioni in formato CalcResultDTO
///
- [HttpPost("PostProcessingResult")]
- public async Task PostProcessingResult(Dictionary ProcResultList)
+ [HttpPost("SaveProcessingResult")]
+ public async Task SaveProcessingResult(List calcResults)
{
- bool answ = false;
- //VC19Check answ = new VC19Check()
- //{
- // Result = "KO"
- //};
- //var result = await _DataService.InsertCheck(DecodedData, "10.74.82.255");
- //if (result)
- //{
- // answ = new VC19Check
- // {
- // DTRecord = DateTime.Now,
- // CheckRecorded = true,
- // TimbrRecorder = true,
- // Result = $"OK, Check Recorded for {DecodedData.nam.fn} {DecodedData.nam.gn} {DecodedData.dob:yyyy.MM.dd}"
- // };
- //}
- //else
- //{ }
- await Task.Delay(1);
- return answ;
- }
-
- ///
- /// Invio elenco risultati elaborazioni come elenco di SVG
- ///
- ///
- ///
- [HttpPost("PostProcessingSvg")]
- public async Task PostProcessingSvg(Dictionary ProcSvgList)
- {
- bool answ = false;
- await Task.Delay(1);
+ bool answ = await QDataServ.SaveProcessingResult(calcResults);
return answ;
}
+#if false
///
/// Elenco richieste in stato pending
///
@@ -111,24 +87,6 @@ namespace WebDoorCreator.API.Controllers
return actQueue;
}
-
- ///
- /// Elenco richieste raggruppate x stato
- ///
- ///
- [HttpGet("ShowQueue")]
- public async Task>> ShowQueue()
- {
- Dictionary> answ = new Dictionary>();
- var actPend = await QDataServ.RequestPending();
- answ.Add("pending", actPend);
-
- var actProc = await QDataServ.RequestProcessing();
- answ.Add("processing", actProc);
- return answ;
- }
-
-
///
/// Elenco richeiste in stato processing
///
@@ -139,6 +97,23 @@ namespace WebDoorCreator.API.Controllers
var actQueue = await QDataServ.RequestProcessing();
return actQueue;
}
+#endif
+
+ ///
+ /// Elenco richieste raggruppate x stato
+ ///
+ ///
+ [HttpGet("StatusList")]
+ public async Task>> StatusList()
+ {
+ Dictionary> answ = new Dictionary>();
+ var actPend = await QDataServ.RequestPending();
+ answ.Add("pending", actPend);
+
+ var actProc = await QDataServ.RequestProcessing();
+ answ.Add("processing", actProc);
+ return answ;
+ }
///
/// Chiede un numero massimo di items dalla coda NB:
diff --git a/WebDoorCreator.Data/DTO/CalcResultDTO.cs b/WebDoorCreator.Data/DTO/CalcResultDTO.cs
new file mode 100644
index 0000000..6679dc8
--- /dev/null
+++ b/WebDoorCreator.Data/DTO/CalcResultDTO.cs
@@ -0,0 +1,35 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace WebDoorCreator.Data.DTO
+{
+ ///
+ /// Oggetto contenitore esiti calcolo
+ ///
+ public class CalcResultDTO
+ {
+ ///
+ /// UID (DoorId.Version)
+ ///
+ public string DoorIdVers { get; set; } = "";
+ ///
+ /// Validated = true / error found = false
+ ///
+ public bool Validated { get; set; } = true;
+ ///
+ /// Error message (optional)
+ ///
+ public string ErrorMsg { get; set; } = "";
+ ///
+ /// SVG generated
+ ///
+ public string SvgGen { get; set; } = "";
+ ///
+ /// Articat path (ex 3d zip/pack)
+ ///
+ public string artifactPath { get; set; } = "";
+ }
+}
diff --git a/WebDoorCreator.Data/Services/QueueDataService.cs b/WebDoorCreator.Data/Services/QueueDataService.cs
index 374c623..88916f6 100644
--- a/WebDoorCreator.Data/Services/QueueDataService.cs
+++ b/WebDoorCreator.Data/Services/QueueDataService.cs
@@ -2,11 +2,10 @@
using Microsoft.Extensions.Configuration;
using Newtonsoft.Json;
using NLog;
-using Org.BouncyCastle.Asn1.Pkcs;
using StackExchange.Redis;
using System.Diagnostics;
using WebDoorCreator.Core;
-using WebDoorCreator.Data;
+using WebDoorCreator.Data.DTO;
namespace WebDoorCreator.Data.Services
{
@@ -64,82 +63,6 @@ namespace WebDoorCreator.Data.Services
redisConn.Dispose();
}
- ///
- /// Invio richiesta di calcolo per la porta indicata, dato il suo DDF
- ///
- ///
- /// Contenuto completo del DDF
- /// indice/versione del calcolo DDF
- public async Task SendCalcReq(int DoorId, string FullDDF)
- {
- int currVers = 1;
- string sDoorId = $"{DoorId}";
- string sCurrVers = "";
- Stopwatch stopWatch = new Stopwatch();
- stopWatch.Start();
-
- // per prima cosa controllo se ho GIA' in coda qualcosa come richeiste
- long numPending = await NumRequestPending();
-
- // se coda non vuota: cerco la DoorId corrente, se c'è sovrascrivo versione altrimenti
- if (numPending != 0)
- {
- var currPending = await RequestPending();
- if (currPending != null)
- {
- if (currPending.ContainsKey(sDoorId))
- {
- sCurrVers = currPending[sDoorId];
- int.TryParse(sCurrVers, out currVers);
- currVers++;
- }
- }
- }
- sCurrVers = $"{currVers}";
- // inserisco in coda
- numPending = await RequestProcessingUpsert(sDoorId, sCurrVers);
-
- // salvo nell'archivio REDIS delle porte il DDF corrente (key=doorId.versNumb), potrebbe
- // venire buono anche x eventuale UNDO...
- RedisKey currDdfKey = new RedisKey($"{Constants.CALC_REQ_DDF_CACHE}:{sDoorId}:{sCurrVers}");
- await redisDb.StringSetAsync(currDdfKey, FullDDF, DayLongCache);
-
- // invio sul canale dei messaggi il numero di items in coda attuali x chiedere esecuzione...
- numPending = await NumRequestPending();
- bool answ = CalcReqPipe.saveAndSendMessage(Constants.LAST_CALC_REQ_KEY, $"{numPending}");
-
-
- stopWatch.Stop();
- TimeSpan ts = stopWatch.Elapsed;
- Log.Debug($"SendCalcReq | DoorId: {DoorId} enqueued in: {ts.TotalMilliseconds} ms");
-
-
- // FIXME TODO!!!! levare quando ci sarà il vero sw in esecuzione...
-
-
- // simulazione ritorno dati...
- string fileName = Path.Combine("temp", $"Logo{idxSim:00}.svg");
- if (File.Exists(fileName))
- {
- // update indici
- idxSim++;
- idxSim = idxSim % 4;
- // leggo file
- string svgCont = File.ReadAllText(fileName);
- // salvo in area REDIS
- RedisKey currSvgKey = new RedisKey($"{Constants.CALC_REQ_SVG_CACHE}:{sDoorId}:{sCurrVers}");
- await redisDb.StringSetAsync(currSvgKey, svgCont, DayLongCache);
-
- }
- // simulo attesa segnalazione messaggio porta calcolata
- await Task.Delay(300);
- string retMess = $"{sDoorId}:{sCurrVers}";
- // invio il FINTO messaggio di ritorno...
- CalcDonePipe.saveAndSendMessage(Constants.LAST_CALC_DONE_KEY, retMess);
-
- return currVers;
- }
-
///
/// Restitusice l'SVG della porta in oggetto
///
@@ -198,6 +121,46 @@ namespace WebDoorCreator.Data.Services
return numReq;
}
+ ///
+ /// Remove for single hash record
+ ///
+ /// Chiave redis della Hashlist
+ /// Chiave nella HashList
+ /// Esito rimozione
+ public async Task RedHashRemove(RedisKey currKey, string chiave)
+ {
+ bool fatto = false;
+ Stopwatch stopWatch = new Stopwatch();
+ stopWatch.Start();
+ fatto = await redisDb.HashDeleteAsync(currKey, chiave);
+ stopWatch.Stop();
+ TimeSpan ts = stopWatch.Elapsed;
+ Log.Trace($"RedHashRemove | {currKey} | in: {ts.TotalMilliseconds} ms");
+ return fatto;
+ }
+
+ ///
+ /// Remove for single hash record
+ ///
+ /// Dictionary of DoorId, saveVersNumb
+ public async Task RequestDoneRemove(string doorId)
+ {
+ RedisKey currKey = new RedisKey(Constants.CALC_REQ_DONE);
+ bool fatto = await RedHashRemove(currKey, doorId);
+ return fatto;
+ }
+
+ ///
+ /// Upsert for single hash record
+ ///
+ /// Dictionary of DoorId, saveVersNumb
+ public async Task RequestDoneUpsert(string doorId, string vers)
+ {
+ RedisKey currKey = new RedisKey(Constants.CALC_REQ_DONE);
+ long numReq = await RedHashUpsert(currKey, doorId, vers);
+ return numReq;
+ }
+
///
/// Get Queue request pending
///
@@ -226,6 +189,27 @@ namespace WebDoorCreator.Data.Services
return dictResult;
}
+ ///
+ /// Remove for single hash record
+ ///
+ /// Dictionary of DoorId, saveVersNumb
+ public async Task RequestPendingRemove(string doorId)
+ {
+ RedisKey currKey = new RedisKey(Constants.CALC_REQ_PEND);
+ bool fatto = await RedHashRemove(currKey, doorId);
+ return fatto;
+ }
+
+ ///
+ /// Upsert for single hash record
+ ///
+ /// Dictionary of DoorId, saveVersNumb
+ public async Task RequestPendingUpsert(string doorId, string vers)
+ {
+ RedisKey currKey = new RedisKey(Constants.CALC_REQ_PEND);
+ long numReq = await RedHashUpsert(currKey, doorId, vers);
+ return numReq;
+ }
///
/// Get Queue request processing
@@ -254,23 +238,99 @@ namespace WebDoorCreator.Data.Services
Log.Debug($"RequestProcessing | {source} in: {ts.TotalMilliseconds} ms");
return dictResult;
}
+
+ ///
+ /// Remove for single hash record
+ ///
+ /// Dictionary of DoorId, saveVersNumb
+ public async Task RequestProcessingRemove(string doorId)
+ {
+ RedisKey currKey = new RedisKey(Constants.CALC_REQ_PROC);
+ bool fatto = await RedHashRemove(currKey, doorId);
+ return fatto;
+ }
+
///
/// Upsert for single hash record
///
/// Dictionary of DoorId, saveVersNumb
public async Task RequestProcessingUpsert(string doorId, string vers)
{
- long numReq = 0;
- // cerco da cache
- RedisKey currKey = new RedisKey(Constants.CALC_REQ_PEND);
+ RedisKey currKey = new RedisKey(Constants.CALC_REQ_PROC);
+ long numReq = await RedHashUpsert(currKey, doorId, vers);
+ return numReq;
+ }
+
+ ///
+ /// Invio richiesta di calcolo per la porta indicata, dato il suo DDF
+ ///
+ ///
+ /// Contenuto completo del DDF
+ /// indice/versione del calcolo DDF
+ public async Task SendCalcReq(int DoorId, string FullDDF)
+ {
+ int currVers = 1;
+ string sDoorId = $"{DoorId}";
+ string sCurrVers = "";
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
- await redisDb.HashSetAsync(currKey, doorId, vers);
- numReq = await redisDb.HashLengthAsync(currKey);
+
+ // per prima cosa controllo se ho GIA' in coda qualcosa come richeiste
+ long numPending = await NumRequestPending();
+
+ // se coda non vuota: cerco la DoorId corrente, se c'è sovrascrivo versione altrimenti
+ if (numPending != 0)
+ {
+ var currPending = await RequestPending();
+ if (currPending != null)
+ {
+ if (currPending.ContainsKey(sDoorId))
+ {
+ sCurrVers = currPending[sDoorId];
+ int.TryParse(sCurrVers, out currVers);
+ currVers++;
+ }
+ }
+ }
+ sCurrVers = $"{currVers}";
+ // inserisco in coda
+ numPending = await RequestPendingUpsert(sDoorId, sCurrVers);
+
+ // salvo nell'archivio REDIS delle porte il DDF corrente (key=doorId.versNumb), potrebbe
+ // venire buono anche x eventuale UNDO...
+ RedisKey currDdfKey = new RedisKey($"{Constants.CALC_REQ_DDF_CACHE}:{sDoorId}:{sCurrVers}");
+ await redisDb.StringSetAsync(currDdfKey, FullDDF, DayLongCache);
+
+ // invio sul canale dei messaggi il numero di items in coda attuali x chiedere esecuzione...
+ numPending = await NumRequestPending();
+ bool answ = CalcReqPipe.saveAndSendMessage(Constants.LAST_CALC_REQ_KEY, $"{numPending}");
+
stopWatch.Stop();
TimeSpan ts = stopWatch.Elapsed;
- Log.Debug($"RequestProcessingUpsert | in: {ts.TotalMilliseconds} ms");
- return numReq;
+ Log.Debug($"SendCalcReq | DoorId: {DoorId} enqueued in: {ts.TotalMilliseconds} ms");
+
+ // FIXME TODO!!!! levare quando ci sarà il vero sw in esecuzione...
+
+ // simulazione ritorno dati...
+ string fileName = Path.Combine("temp", $"Logo{idxSim:00}.svg");
+ if (File.Exists(fileName))
+ {
+ // update indici
+ idxSim++;
+ idxSim = idxSim % 4;
+ // leggo file
+ string svgCont = File.ReadAllText(fileName);
+ // salvo in area REDIS
+ RedisKey currSvgKey = new RedisKey($"{Constants.CALC_REQ_SVG_CACHE}:{sDoorId}:{sCurrVers}");
+ await redisDb.StringSetAsync(currSvgKey, svgCont, DayLongCache);
+ }
+ // simulo attesa segnalazione messaggio porta calcolata
+ await Task.Delay(300);
+ string retMess = $"{sDoorId}:{sCurrVers}";
+ // invio il FINTO messaggio di ritorno...
+ CalcDonePipe.saveAndSendMessage(Constants.LAST_CALC_DONE_KEY, retMess);
+
+ return currVers;
}
///
@@ -279,7 +339,7 @@ namespace WebDoorCreator.Data.Services
/// Dictionary of DoorId, saveVersNumb
public async Task> TakeProcessingItems(int numItems)
{
- string source = "REDIS";
+ int maxTake = 10;
long numReq = 0;
Dictionary dictResult = new Dictionary();
// cerco da cache
@@ -290,20 +350,41 @@ namespace WebDoorCreator.Data.Services
if (numReq > 0)
{
var rawData = await redisDb.HashGetAllAsync(currKey);
+ // sposto fino a concorrenza...
foreach (var item in rawData)
{
+ maxTake--;
dictResult.Add($"{item.Name}", $"{item.Value}");
+ // sposto tra le 2 code
+ await RequestProcessingUpsert(item.Name, item.Value);
+ await RequestPendingRemove(item.Name);
+ if (maxTake <= 0)
+ {
+ break;
+ }
}
}
stopWatch.Stop();
TimeSpan ts = stopWatch.Elapsed;
- Log.Debug($"TakeProcessingItems | {source} in: {ts.TotalMilliseconds} ms");
+ Log.Debug($"TakeProcessingItems | REDIS in: {ts.TotalMilliseconds} ms");
return dictResult;
}
+ ///
+ /// Invio elenco risultati elaborazioni (modalità boolean di esecuzione corretta)
+ ///
+ /// Risultati elaborazioni in formato CalcResultDTO
+ ///
+ public async Task SaveProcessingResult(List calcResults)
+ {
+ bool answ = false;
+ await Task.Delay(1);
+ return answ;
+ }
+
#endregion Public Methods
- #region Protected Fields
+ #region Protected Fields
protected const string rKeyCalcOreFase = "Check:OreFasi";
@@ -340,6 +421,26 @@ namespace WebDoorCreator.Data.Services
return answ;
}
+ ///
+ /// Effettua upsert in HasList redis
+ ///
+ /// Chiave redis della Hashlist
+ /// Chiave nella HashList
+ /// Valore da salvare
+ /// Num record nella HashList
+ protected async Task RedHashUpsert(RedisKey currKey, string chiave, string valore)
+ {
+ long numReq = 0;
+ Stopwatch stopWatch = new Stopwatch();
+ stopWatch.Start();
+ await redisDb.HashSetAsync(currKey, chiave, valore);
+ numReq = await redisDb.HashLengthAsync(currKey);
+ stopWatch.Stop();
+ TimeSpan ts = stopWatch.Elapsed;
+ Log.Trace($"RedHashUpsert | {currKey} | in: {ts.TotalMilliseconds} ms");
+ return numReq;
+ }
+
///
/// Salvataggio chiave in redis
///
@@ -423,6 +524,14 @@ namespace WebDoorCreator.Data.Services
#region Private Properties
+ ///
+ /// Durata cache di 24h
+ ///
+ private TimeSpan DayLongCache
+ {
+ get => TimeSpan.FromHours(24);
+ }
+
///
/// Durata cache lunga (+ perturbazione percentuale +/-10%)
///
@@ -447,14 +556,6 @@ namespace WebDoorCreator.Data.Services
get => TimeSpan.FromSeconds(cacheTtlLong * 10 * rnd.Next(900, 1100) / 1000);
}
- ///
- /// Durata cache di 24h
- ///
- private TimeSpan DayLongCache
- {
- get => TimeSpan.FromHours(24);
- }
-
#endregion Private Properties
#region Private Methods
diff --git a/WebDoorCreator.UI/temp/Conf.yaml b/WebDoorCreator.UI/temp/Conf.yaml
index 861a811..1a0ecf8 100644
--- a/WebDoorCreator.UI/temp/Conf.yaml
+++ b/WebDoorCreator.UI/temp/Conf.yaml
@@ -3,7 +3,7 @@
#Door1
code: 0015943
-date: 2023-04-19T13:38:20.6194164+02:00
+date: 2023-04-19T14:05:03.5064525+02:00
material: wood
measures: millimiters
order: