- spostato servizi da WDCDataService a servizio in Data
- inizio modifica comportamento invio richieste calcolo e risposte
This commit is contained in:
Samuele Locatelli
2023-04-19 11:15:37 +02:00
parent 91641a8936
commit 5b6ccd560d
8 changed files with 156 additions and 180 deletions
@@ -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
/// <summary>
/// Classe Accesso metodi DB
/// </summary>
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
/// <summary>
/// Message pipe esecuzione elaborazione CAM --> UI
/// </summary>
public MessagePipe calcDonePipe { get; set; } = null!;
/// <summary>
/// Message pipe richieste elaborazione UI --> CAM
/// </summary>
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
/// <summary>
/// Doors list by orderId
/// </summary>
@@ -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<bool> FlushRedisCache()
{
await Task.Delay(1);
RedisValue pattern = new RedisValue($"{Constants.BASE_HASH}:Cache*");
bool answ = await ExecFlushRedisPattern(pattern);
return answ;
}
/// <summary>
/// Esegue flush memoria redis dato pattern
/// </summary>
/// <param name="pattern"></param>
/// <returns></returns>
private async Task<bool> 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<bool> 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;
/// <summary>
/// Get # of calculation request pending
@@ -231,6 +316,55 @@ namespace WebDoorCreator.API.Data
return dictResult;
}
/// <summary>
/// Enqueue DDF processing req from UI
/// </summary>
/// <param name="DoorId"></param>
/// <param name="FullDDF">Contenuto completo del DDF</param>
/// <returns>Version / iteration on DDF processing request</returns>
public async Task<int> 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
@@ -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}");
}
}
}
@@ -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
@@ -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}"));
// }
// }
// }
@@ -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
@@ -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
/// <summary>
/// Message pipe esecuzione elaborazione CAM --&gt; UI
/// </summary>
public MessagePipe calcDonePipe { get; set; } = null!;
/// <summary>
/// Message pipe richieste elaborazione UI --&gt; CAM
/// </summary>
public MessagePipe calcReqPipe { get; set; } = null!;
#endregion Public Properties
#region Public Methods
public void Dispose()
{
redisConn.Dispose();
}
public async Task<bool> FlushRedisCache()
{
await Task.Delay(1);
RedisValue pattern = new RedisValue($"{Constants.BASE_HASH}:Cache*");
bool answ = await ExecFlushRedisPattern(pattern);
return answ;
}
public async Task<bool> 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
/// <summary>
/// Conf allarmi (BankBit) IMPOSTATA con valori silenziati
/// </summary>
/// <returns></returns>
public async Task<List<BaseAlarmBankConf>> getAlarmBankBitSetup()
{
List<BaseAlarmBankConf>? redResult = new List<BaseAlarmBankConf>();
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<List<BaseAlarmBankConf>>(rawData);
}
// altrimenti imposto vuoto
if (redResult == null)
{
redResult = new List<BaseAlarmBankConf>();
}
return await Task.FromResult(redResult);
}
#endif
/// <summary>
/// Oggetto per connessione a REDIS
/// </summary>
private ConnectionMultiplexer redisConn = null!;
//ISubscriber sub = redis.GetSubscriber();
/// <summary>
/// Oggetto DB redis da impiegare x chiamate R/W
/// </summary>
private IDatabase redisDb = null!;
#endregion Private Fields
#region Private Methods
/// <summary>
/// Esegue flush memoria redis dato pattern
/// </summary>
/// <param name="pattern"></param>
/// <returns></returns>
private async Task<bool> 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
}
}
@@ -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;
+5 -1
View File
@@ -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<WebDoorCreatorService>();
builder.Services.AddScoped<WDCUserService>();
builder.Services.AddSingleton<WDCVocabularyService>();
builder.Services.AddSingleton<WDCCurrDataService>();
#if false
builder.Services.AddSingleton<WDCCurrDataService>();
#endif
builder.Services.AddSingleton<QueueDataService>();
builder.Services.AddScoped<AuthenticationStateProvider, RevalidatingIdentityAuthenticationStateProvider<IdentityUser>>();
builder.Services.AddHttpContextAccessor();
builder.Services.AddSingleton<IConnectionMultiplexer>(redisMultiplexer);