Files
webdoorcreator/WebDoorCreator.API/Controllers/QueueController.cs
T
Samuele Locatelli 4cde37cd5f Inserita gestione tipo richiesta (svg/3dm)
Rimesso bottone x export 3d con timeout x risposta calcolo
2024-06-27 15:34:15 +02:00

224 lines
7.8 KiB
C#

using Microsoft.AspNetCore.Mvc;
using NLog;
using System.Diagnostics;
using WebDoorCreator.Core;
using WebDoorCreator.Data.DTO;
using WebDoorCreator.Data.Services;
namespace WebDoorCreator.API.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class QueueController : ControllerBase
{
#region Public Constructors
public QueueController(IConfiguration configuration, QueueDataService DataService, WebDoorCreatorService _WDService)
{
_configuration = configuration;
logTimingEnable = configuration.GetValue<bool>("RuntimeOpt:LogTimingEnable");
QDataServ = DataService;
WDService = _WDService;
// aggiungo..
string statName = "QueueController";
bool doWrite = QDataServ.StatUpsert(statName, new TimeSpan(), 5).Result;
// se campione "pieno"...
if (doWrite)
{
// recupero e resetto
ExecStats statRec = QDataServ.StatReset(statName).Result;
Log.Trace($"Avviato QueueController x {statRec.NumCall}");
}
}
#endregion Public Constructors
#region Public Methods
/// <summary>
/// Lunghezza coda in fase di processing
/// </summary>
/// <returns></returns>
[HttpGet("ActLenght")]
public async Task<Dictionary<string, long>> ActLenght()
{
Dictionary<string, long> answ = new Dictionary<string, long>();
var actPend = await QDataServ.NumRequestPending();
answ.Add("pending", actPend);
var actProc = await QDataServ.NumRequestProcessing();
answ.Add("processing", actProc);
var actErr = await QDataServ.NumRequestErrors();
answ.Add("errors", actErr);
var actDone = await QDataServ.NumRequestDone();
answ.Add("done", actDone);
return answ;
}
/// <summary>
/// Cleanup dati delle code di calcolo
/// </summary>
/// <param name="passPhrase">Chiave x auth di reset</param>
/// <returns></returns>
[HttpPost("DCCacheCleanup")]
public async Task<string> DCCacheCleanup(string passPhrase)
{
string answ = "NA";
bool fatto = false;
if (passPhrase == "bbbBirdIsTheWord")
{
fatto = await QDataServ.DoorCalcCacheCleanup();
}
answ = fatto ? "OK" : "NO";
return answ;
}
/// <summary>
/// Reset delle code di chiamata x ripetere simulazione
/// </summary>
/// <param name="passPhrase">Chiave x auth di reset</param>
/// <returns></returns>
[HttpPost("ResetQueue")]
public async Task<string> ResetQueue(string passPhrase)
{
string answ = "NA";
bool fatto = false;
if (passPhrase == "bbbBirdIsTheWord")
{
fatto = await QDataServ.ResetQueue();
}
answ = fatto ? "OK" : "NO";
return answ;
}
/// <summary>
/// Reset della coda di processing x evitare condizioni di "stuck in calc"
/// </summary>
/// <returns></returns>
[HttpPost("ResetQueueProcessing")]
public async Task<string> ResetQueueProcessing()
{
string answ = "NA";
// fixme todo
/* --------------
* da riscrivere
* - server record x cancellazione logica delle porte OK
* - il record (boolean, toDelete...) indica azione richiesta OK
* - si prendono TUTTE le porte da DB con toDelete == true OK
* - si eliminano su REDIS dalle 4 code (req, processing, error, done) OK
* - check delle code processing, SE ci sono record rimasti li cerco sul DB
* - se NON ci sono sul db --> li elimino da processing
* - effettivo delete sul db di toDelete
*
* - proseguo come ora (sposto tra code processing --> request)
*/
var doors2Del = await WDService.DoorGet2Del();
if (doors2Del != null)
{
foreach (var item in doors2Del)
{
await WDService.RedisBulkDelByDoorId(item.DoorId);
await QDataServ.RedisBulkDelHashByKey(item.DoorId);
await WDService.DoorDelete(item);
}
}
bool fatto = await QDataServ.ResetQueueProcessing();
answ = fatto ? "OK" : "NO";
return answ;
}
/// <summary>
/// Invio elenco risultati elaborazioni (modalità boolean di esecuzione corretta)
/// </summary>
/// <param name="calcResults">Risultati elaborazioni in formato CalcResultDTO</param>
/// <returns></returns>
[HttpPost("SaveProcResult")]
public async Task<string> SaveProcResult(List<CalcResultDTO> calcResults)
{
string answ = "NA";
bool fatto = await QDataServ.SaveProcessingResult(calcResults);
answ = fatto ? "OK" : "NO";
Log.Debug("Eseguito SaveProcResult");
return answ;
}
/// <summary>
/// Elenco richieste raggruppate x stato
/// </summary>
/// <returns></returns>
[HttpGet("StatusList")]
public async Task<Dictionary<string, Dictionary<string, string>>> StatusList()
{
Stopwatch sw = new Stopwatch();
if (logTimingEnable)
{
sw.Start();
}
Dictionary<string, Dictionary<string, string>> answ = new Dictionary<string, Dictionary<string, string>>();
var actPend = await QDataServ.RequestPending();
answ.Add("pending", actPend);
var actProc = await QDataServ.RequestProcessing();
answ.Add("processing", actProc);
var actErr = await QDataServ.RequestErr();
answ.Add("errors", actErr);
var actDone = await QDataServ.RequestDone();
answ.Add("done", actDone);
if (logTimingEnable)
{
sw.Stop();
// aggiungo..
string statName = "StatusList";
bool doWrite = await QDataServ.StatUpsert(statName, sw.Elapsed, 5);
// se campione "pieno"...
if (doWrite)
{
// recupero e resetto
ExecStats statRec = await QDataServ.StatReset(statName);
Log.Info($"Eseguito {statName} x {statRec.NumCall} | {statRec.AvgTime.TotalMilliseconds:N3}ms");
}
}
return answ;
}
/// <summary>
/// Chiede un numero massimo di items dalla coda NB:
/// - verranno tolti dalla coda FIFO richieste
/// - verranno messi nella coda FIFO processing
/// </summary>
/// <returns></returns>
[HttpGet("TakeNextItems")]
public async Task<Dictionary<string, CalcReqtDTO>> TakeProcessingItems(int numItems = 10)
{
var actQueue = await QDataServ.TakeProcessingItems(numItems);
Log.Debug($"Eseguito TakeProcessingItems per {numItems} items");
return actQueue;
}
#endregion Public Methods
#region Private Fields
private static Logger Log = LogManager.GetCurrentClassLogger();
private IConfiguration _configuration = null!;
private bool logTimingEnable = false;
#endregion Private Fields
#region Private Properties
private QueueDataService QDataServ { get; set; } = null!;
private WebDoorCreatorService WDService { get; set; } = null!;
#endregion Private Properties
}
}