Update vari x gestione redis ottimizzata
This commit is contained in:
@@ -1,18 +1,10 @@
|
||||
using EgwCoreLib.Razor;
|
||||
using IOB_MAN.Core;
|
||||
using IOB_MAN.Core.DTO;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using IOB_MAN.Core.DTO;
|
||||
using Newtonsoft.Json;
|
||||
using NLog;
|
||||
using StackExchange.Redis;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Runtime;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Threading.Channels;
|
||||
|
||||
namespace IOB_MAN.Core.Data
|
||||
{
|
||||
@@ -44,14 +36,15 @@ namespace IOB_MAN.Core.Data
|
||||
{
|
||||
// init REDIS obj
|
||||
RedisConnMPlex = redisMultiplex;
|
||||
RedisDb = this.RedisConnMPlex.GetDatabase();
|
||||
RedisDb = RedisConnMPlex.GetDatabase();
|
||||
RedisSubs = RedisConnMPlex.GetSubscriber();
|
||||
// json serializer... FIX errore loop circolare https://www.ryadel.com/en/jsonserializationexception-self-referencing-loop-detected-error-fix-entity-framework-asp-net-core/
|
||||
JSSettings = new JsonSerializerSettings()
|
||||
{
|
||||
ReferenceLoopHandling = ReferenceLoopHandling.Ignore
|
||||
};
|
||||
// init classe sottoscrizione PubSub CHannel messages REDIS
|
||||
messageDisp.Subscribe(ChannelName(codIob), (channel, message) =>
|
||||
RedisSubs.Subscribe(ChannelName(codIob), (channel, message) =>
|
||||
{
|
||||
SaveIobStatus(channel, message);
|
||||
});
|
||||
@@ -486,8 +479,10 @@ namespace IOB_MAN.Core.Data
|
||||
{
|
||||
for (int i = 0; i < numAnsw; i++)
|
||||
{
|
||||
Int32.TryParse(valori[i], out currVal);
|
||||
answ.Add(new KeyValuePair<string, int>(chiavi[i], currVal));
|
||||
if (int.TryParse(valori[i], out currVal))
|
||||
{
|
||||
answ.Add(new KeyValuePair<string, int>($"{chiavi[i]}", currVal));
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception exc)
|
||||
@@ -536,8 +531,11 @@ namespace IOB_MAN.Core.Data
|
||||
int i = 0;
|
||||
foreach (HashEntry item in valori)
|
||||
{
|
||||
answ[i] = new KeyValuePair<string, string>(item.Name, item.Value);
|
||||
i++;
|
||||
if (item.Name.HasValue)
|
||||
{
|
||||
answ[i] = new KeyValuePair<string, string>($"{item.Name}", $"{item.Value}");
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception exc)
|
||||
@@ -562,7 +560,10 @@ namespace IOB_MAN.Core.Data
|
||||
HashEntry[] valori = RedisDb.HashGetAll(chiave);
|
||||
foreach (HashEntry item in valori)
|
||||
{
|
||||
answ.Add(item.Name, item.Value);
|
||||
if (item.Name.HasValue)
|
||||
{
|
||||
answ.Add($"{item.Name}", $"{item.Value}");
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception exc)
|
||||
@@ -693,7 +694,7 @@ namespace IOB_MAN.Core.Data
|
||||
int i = 0;
|
||||
foreach (KeyValuePair<string, string> kvp in hashFields)
|
||||
{
|
||||
valori[i] = new HashEntry(kvp.Key, kvp.Value);
|
||||
valori[i] = new HashEntry($"{kvp.Key}", $"{kvp.Value}");
|
||||
i++;
|
||||
}
|
||||
RedisDb.HashSet(chiave, valori);
|
||||
@@ -753,7 +754,7 @@ namespace IOB_MAN.Core.Data
|
||||
int i = 0;
|
||||
foreach (KeyValuePair<string, string> kvp in hashFields)
|
||||
{
|
||||
valori[i] = new HashEntry(kvp.Key, kvp.Value);
|
||||
valori[i] = new HashEntry($"{kvp.Key}", $"{kvp.Value}");
|
||||
i++;
|
||||
}
|
||||
RedisDb.HashSet(chiave, valori);
|
||||
@@ -805,27 +806,22 @@ namespace IOB_MAN.Core.Data
|
||||
public bool redSaveHashList(string hashKey, List<KeyValuePair<string, string>> hashListKVP)
|
||||
{
|
||||
bool answ = false;
|
||||
if (RedisConnMPlex.IsConnected)
|
||||
try
|
||||
{
|
||||
// cerco se ci sia valore in redis...
|
||||
IDatabase cache = RedisConnMPlex.GetDatabase();
|
||||
try
|
||||
RedisKey chiave = hashKey;
|
||||
HashEntry[] valori = new HashEntry[hashListKVP.Count];
|
||||
int i = 0;
|
||||
foreach (KeyValuePair<string, string> kvp in hashListKVP)
|
||||
{
|
||||
RedisKey chiave = hashKey;
|
||||
HashEntry[] valori = new HashEntry[hashListKVP.Count];
|
||||
int i = 0;
|
||||
foreach (KeyValuePair<string, string> kvp in hashListKVP)
|
||||
{
|
||||
valori[i] = new HashEntry(kvp.Key, kvp.Value);
|
||||
i++;
|
||||
}
|
||||
cache.HashSet(chiave, valori);
|
||||
answ = true;
|
||||
}
|
||||
catch (Exception exc)
|
||||
{
|
||||
Log.Error($"redSaveHashList:{Environment.NewLine}{exc}");
|
||||
valori[i] = new HashEntry(kvp.Key, kvp.Value);
|
||||
i++;
|
||||
}
|
||||
RedisDb.HashSet(chiave, valori);
|
||||
answ = true;
|
||||
}
|
||||
catch (Exception exc)
|
||||
{
|
||||
Log.Error($"redSaveHashList:{Environment.NewLine}{exc}");
|
||||
}
|
||||
return answ;
|
||||
}
|
||||
@@ -970,34 +966,6 @@ namespace IOB_MAN.Core.Data
|
||||
|
||||
#endregion Public Methods
|
||||
|
||||
#region Protected Properties
|
||||
|
||||
/// <summary>
|
||||
/// Message Dispatcher: oggetto comunicazione pub/sub via REDIS channels corrente
|
||||
/// </summary>
|
||||
protected ISubscriber messageDisp
|
||||
{
|
||||
get
|
||||
{
|
||||
ISubscriber answ;
|
||||
// se già valorizzato uso oggetto private...
|
||||
if (_currSub != null)
|
||||
{
|
||||
answ = _currSub;
|
||||
}
|
||||
else
|
||||
{
|
||||
// sottoscrizione al dispatcher messaggi
|
||||
answ = RedisConnMPlex.GetSubscriber();
|
||||
_currSub = answ;
|
||||
}
|
||||
// restituisco oggetto DB
|
||||
return answ;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion Protected Properties
|
||||
|
||||
#region Protected Methods
|
||||
|
||||
protected void CleanExpiredEvents(string rkeyTS, string rkeyHash, int minutesBack, int batchSize = 1000)
|
||||
@@ -1224,12 +1192,13 @@ namespace IOB_MAN.Core.Data
|
||||
|
||||
private double lastFLRatio = 0;
|
||||
|
||||
#if DEBUG
|
||||
private long NumChannelCall = 0;
|
||||
|
||||
private long NumReadCache = 0;
|
||||
|
||||
private long NumReadLast = 0;
|
||||
|
||||
private long NumReadPubSub = 0;
|
||||
#endif
|
||||
|
||||
/// <summary>
|
||||
/// Random genertor
|
||||
@@ -1252,24 +1221,27 @@ namespace IOB_MAN.Core.Data
|
||||
private IDatabase RedisDb = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Hash redis x dati server
|
||||
/// Message Dispatcher: oggetto comunicazione pub/sub via REDIS channels corrente
|
||||
/// </summary>
|
||||
private string RedServKey = "";
|
||||
private ISubscriber RedisSubs;
|
||||
|
||||
#if DEBUG
|
||||
#endif
|
||||
|
||||
/// <summary>
|
||||
/// Hash redis x dati MAN
|
||||
/// </summary>
|
||||
private string RedManKey = "";
|
||||
|
||||
/// <summary>
|
||||
/// Hash redis x dati server
|
||||
/// </summary>
|
||||
private string RedServKey = "";
|
||||
|
||||
#endregion Private Fields
|
||||
|
||||
#region Private Properties
|
||||
|
||||
/// <summary>
|
||||
/// Oggetto subscriber x pubblicazione/sottoscrizione canali REDIS
|
||||
/// </summary>
|
||||
private ISubscriber _currSub { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Verifica validità dati channel (quando refresh ricevuto entro periodo validità)
|
||||
/// </summary>
|
||||
@@ -1290,9 +1262,11 @@ namespace IOB_MAN.Core.Data
|
||||
|
||||
#region Private Methods
|
||||
|
||||
private string ChannelName(string codIob)
|
||||
private RedisChannel ChannelName(string codIob)
|
||||
{
|
||||
return $"IobChannel_{codIob}";
|
||||
string chName = $"IobChannel_{codIob}";
|
||||
RedisChannel rChannel = new RedisChannel($"IobChannel_{codIob}", RedisChannel.PatternMode.Literal);
|
||||
return rChannel;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -1588,6 +1562,5 @@ namespace IOB_MAN.Core.Data
|
||||
}
|
||||
|
||||
#endregion Private Methods
|
||||
|
||||
}
|
||||
}
|
||||
+11
-12
@@ -9,18 +9,6 @@ namespace IOB_MAN.Core
|
||||
{
|
||||
public class IobAdapt : IDisposable
|
||||
{
|
||||
public void Dispose()
|
||||
{
|
||||
CodIOB = "";
|
||||
pID = 0;
|
||||
ExeName = "";
|
||||
TgtName = "";
|
||||
isRunning = false;
|
||||
// initi redis
|
||||
redisMan = null;
|
||||
GC.Collect();
|
||||
}
|
||||
|
||||
#region Public Constructors
|
||||
|
||||
/// <summary>
|
||||
@@ -228,6 +216,17 @@ namespace IOB_MAN.Core
|
||||
|
||||
#endregion Public Properties
|
||||
|
||||
#region Public Methods
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
isRunning = false;
|
||||
redisMan = null;
|
||||
GC.Collect();
|
||||
}
|
||||
|
||||
#endregion Public Methods
|
||||
|
||||
#region Protected Fields
|
||||
|
||||
protected int maxVeto = 3000;
|
||||
|
||||
@@ -1080,8 +1080,8 @@ namespace IOB_MAN.Core.Services
|
||||
if (!File.Exists(item.Value.NLogPath))
|
||||
{
|
||||
// verifico folder parent...
|
||||
string parentDir = Path.GetDirectoryName(item.Value.NLogPath);
|
||||
if (!Directory.Exists(parentDir))
|
||||
string parentDir = Path.GetDirectoryName(item.Value.NLogPath) ?? "";
|
||||
if (!string.IsNullOrEmpty(parentDir) && !Directory.Exists(parentDir))
|
||||
{
|
||||
Directory.CreateDirectory(parentDir);
|
||||
}
|
||||
|
||||
@@ -333,7 +333,10 @@ namespace IOB_MAN.Core.Services
|
||||
HashEntry[] valori = RedisDb.HashGetAll(chiave);
|
||||
foreach (HashEntry item in valori)
|
||||
{
|
||||
answ.Add(item.Name, item.Value);
|
||||
if (item.Name.HasValue && item.Value.HasValue)
|
||||
{
|
||||
answ.Add($"{item.Name}", $"{item.Value}");
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception exc)
|
||||
|
||||
@@ -72,7 +72,6 @@
|
||||
<div class="card-body px-2 py-1">
|
||||
@if (dxMenuVisible)
|
||||
{
|
||||
@* <ul class="dropdown-menu" style="@contextMenuStyle"> *@
|
||||
<ul class="list-group small" style="@contextMenuStyle">
|
||||
@if (selIOB != null && !string.IsNullOrEmpty(selIOB.CodIOB))
|
||||
{
|
||||
@@ -83,15 +82,15 @@
|
||||
<li class="list-group-item list-group-item-primary" @onclick="() => OpenFLForm()"><i class="fa-solid fa-gear me-2"></i> @selIOB.CodIOB | Pareto FluxLog + Config</li>
|
||||
<button type="button" class="list-group-item list-group-item-action list-group-item-danger" @onclick="() => DoCloseChild(selIOB)"><i class="fa-solid fa-stop me-2 text-danger"></i> <b>Close</b> @selIOB.CodIOB</button>
|
||||
}
|
||||
else
|
||||
@* else
|
||||
{
|
||||
<button type="button" class="list-group-item list-group-item-action list-group-item-success disabled"><i class="fa-solid fa-play me-2 text-success"></i> <b>Restart</b> @selIOB.CodIOB</button>
|
||||
<button type="button" class="list-group-item list-group-item-action list-group-item-success disabled"><i class="fa-solid fa-play me-2 text-success"></i> <b>Restart</b> IOB</button>
|
||||
<button type="button" class="list-group-item list-group-item-action list-group-item-info2 disabled"><i class="fa-solid fa-folder-open me-2"></i> Open <b>LOG</b> Folder</button>
|
||||
<button type="button" class="list-group-item list-group-item-action list-group-item-secondary2 disabled"><i class="fa-solid fa-folder-open me-2"></i> Open <b>CONF</b> Folder</button>
|
||||
<button type="button" class="list-group-item list-group-item-action list-group-item-success2 disabled"><i class="fa-solid fa-folder-open me-2"></i> Open <b>APP</b> Folder</button>
|
||||
<li class="list-group-item list-group-item-primary disabled"><i class="fa-solid fa-gear me-2"></i> @selIOB.CodIOB | Pareto FluxLog + Config</li>
|
||||
<button type="button" class="list-group-item list-group-item-action list-group-item-danger disabled"><i class="fa-solid fa-stop me-2 text-danger"></i> <b>Close</b> @selIOB.CodIOB</button>
|
||||
}
|
||||
<li class="list-group-item list-group-item-primary disabled"><i class="fa-solid fa-gear me-2"></i> IOB | Pareto FluxLog + Config</li>
|
||||
<button type="button" class="list-group-item list-group-item-action list-group-item-danger disabled"><i class="fa-solid fa-stop me-2 text-danger"></i> <b>Close</b> IOB</button>
|
||||
} *@
|
||||
</ul>
|
||||
}
|
||||
|
||||
|
||||
@@ -337,7 +337,10 @@ namespace IOB_MAN.Components.Compo
|
||||
|
||||
private string countAutoRestart = "";
|
||||
|
||||
#if false
|
||||
private int currVal = 100;
|
||||
private int nextVal = 100;
|
||||
#endif
|
||||
|
||||
private bool dxMenuVisible = false;
|
||||
|
||||
@@ -347,7 +350,6 @@ namespace IOB_MAN.Components.Compo
|
||||
|
||||
private string menuYpx = "0px";
|
||||
|
||||
private int nextVal = 100;
|
||||
|
||||
private IobAdapt? selIOB = null;
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ namespace IOB_MAN.Components.Compo
|
||||
get => searchRecords;
|
||||
set
|
||||
{
|
||||
if (searchRecords != value)
|
||||
if (!searchRecords.Equals(value))
|
||||
{
|
||||
currSelId = "";
|
||||
searchRecords = value;
|
||||
@@ -30,8 +30,6 @@ namespace IOB_MAN.Components.Compo
|
||||
}
|
||||
}
|
||||
|
||||
private List<FluxLogStatsDTO.ParetoVals> searchRecords { get; set; } = new List<FluxLogStatsDTO.ParetoVals>();
|
||||
|
||||
#endregion Public Properties
|
||||
|
||||
#region Protected Properties
|
||||
@@ -42,15 +40,16 @@ namespace IOB_MAN.Components.Compo
|
||||
|
||||
#region Protected Methods
|
||||
|
||||
protected string CssCheckSelect(FluxLogStatsDTO.ParetoVals currRec)
|
||||
{
|
||||
return currRec.Valore == currSelId ? "active" : "";
|
||||
}
|
||||
protected string CssBadge(FluxLogStatsDTO.ParetoVals currRec)
|
||||
{
|
||||
return currRec.Valore == currSelId ? "text-bg-dark" : "text-bg-primary";
|
||||
}
|
||||
|
||||
protected string CssCheckSelect(FluxLogStatsDTO.ParetoVals currRec)
|
||||
{
|
||||
return currRec.Valore == currSelId ? "active" : "";
|
||||
}
|
||||
|
||||
protected override void OnParametersSet()
|
||||
{
|
||||
ForceReload();
|
||||
@@ -96,16 +95,19 @@ namespace IOB_MAN.Components.Compo
|
||||
#region Private Fields
|
||||
|
||||
private int currPage = 0;
|
||||
|
||||
private string currSelId = "";
|
||||
|
||||
private bool isLoading = false;
|
||||
private int numRecord = 10;
|
||||
|
||||
private int totalCount = 0;
|
||||
|
||||
#endregion Private Fields
|
||||
|
||||
#region Private Properties
|
||||
|
||||
private List<FluxLogStatsDTO.ParetoVals> searchRecords { get; set; } = new List<FluxLogStatsDTO.ParetoVals>();
|
||||
|
||||
#endregion Private Properties
|
||||
|
||||
#region Private Methods
|
||||
|
||||
private void ForceReload()
|
||||
|
||||
@@ -230,18 +230,21 @@ namespace IOB_MAN.Components.Pages
|
||||
DateTime adesso = DateTime.Now;
|
||||
// faccio backup
|
||||
string fileNameOnly = Path.GetFileName(currConfFile);
|
||||
string baseDir = Path.GetDirectoryName(currConfFile);
|
||||
string bcfFile = Path.Combine(baseDir, $"{fileNameOnly}_{adesso:yyMMdd-HHmmss}.bck");
|
||||
File.Copy(currConfFile, bcfFile);
|
||||
// serializzo e salvo...
|
||||
JsonSerializerSettings jsSet = new JsonSerializerSettings()
|
||||
string baseDir = Path.GetDirectoryName(currConfFile) ?? "";
|
||||
if (!string.IsNullOrEmpty(baseDir))
|
||||
{
|
||||
Formatting = Formatting.Indented,
|
||||
NullValueHandling = NullValueHandling.Ignore,
|
||||
Culture = CultureInfo.InvariantCulture
|
||||
};
|
||||
string rawData = JsonConvert.SerializeObject(currMem, jsSet);
|
||||
File.WriteAllText(currConfFile, rawData);
|
||||
string bcfFile = Path.Combine(baseDir, $"{fileNameOnly}_{adesso:yyMMdd-HHmmss}.bck");
|
||||
File.Copy(currConfFile, bcfFile);
|
||||
// serializzo e salvo...
|
||||
JsonSerializerSettings jsSet = new JsonSerializerSettings()
|
||||
{
|
||||
Formatting = Formatting.Indented,
|
||||
NullValueHandling = NullValueHandling.Ignore,
|
||||
Culture = CultureInfo.InvariantCulture
|
||||
};
|
||||
string rawData = JsonConvert.SerializeObject(currMem, jsSet);
|
||||
File.WriteAllText(currConfFile, rawData);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
<Nullable>enable</Nullable>
|
||||
<UseWindowsForms>true</UseWindowsForms>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Version>4.0.2507.2107</Version>
|
||||
<Version>4.0.2507.2418</Version>
|
||||
<Configurations>Debug;Release;Remote_DEBUG</Configurations>
|
||||
<IncludeSourceRevisionInInformationalVersion>false</IncludeSourceRevisionInInformationalVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
Reference in New Issue
Block a user