Merge branch 'release/AddRedisHashDelKey'

This commit is contained in:
Samuele Locatelli
2023-11-29 08:53:29 +01:00
3 changed files with 375 additions and 293 deletions
+23
View File
@@ -323,6 +323,29 @@ namespace SteamWare.IO
return answ;
}
/// <summary>
/// ELIMINA un SINGOLO VALORE dalla hash (dato field = chiave)
/// </summary>
/// <param name="hashKey"></param>
/// <param name="hashField"></param>
/// <returns></returns>
public bool redDelHashField(string hashKey, string hashField)
{
bool answ = false;
// cerco se ci sia valore in redis...
try
{
RedisKey chiave = hashKey;
RedisValue campo = hashField;
answ = cache.HashDelete(chiave, campo);
}
catch (Exception exc)
{
Log.Error($"Errore in redDelHashField{Environment.NewLine}{exc}");
}
return answ;
}
/// <summary>
/// Elimina una key (hash, string)
/// </summary>
+329 -293
View File
@@ -19,52 +19,6 @@ namespace SteamWare.IO
/// </summary>
public class memLayer
{
#region Private Fields
/// <summary>
/// Connessione lazy a redis...
/// </summary>
private Lazy<ConnectionMultiplexer> lazyConnection = new Lazy<ConnectionMultiplexer>(() =>
{
string RedisConn = memLayer.ML.confReadString("RedisConn");
if (string.IsNullOrEmpty(RedisConn))
{
RedisConn = "localhost,abortConnect=false,ssl=false";
}
return ConnectionMultiplexer.Connect(RedisConn);
});
/// <summary>
/// Connessione lazy a redis...
/// </summary>
private Lazy<ConnectionMultiplexer> lazyConnectionAdmin = new Lazy<ConnectionMultiplexer>(() =>
{
string RedisConnAdmin = memLayer.ML.confReadString("RedisConnAdmin");
if (string.IsNullOrEmpty(RedisConnAdmin))
{
RedisConnAdmin = "localhost,abortConnect=false,ssl=false,allowAdmin=true";
}
return ConnectionMultiplexer.Connect(RedisConnAdmin);
});
#endregion Private Fields
#region Protected Fields
/// <summary>
/// lettore file configurazione
/// </summary>
protected AppSettingsReader configAppSetReader;
/// <summary>
/// Oggetto MongoDbCLient x accesso al motore
/// </summary>
protected MongoClient currMongoClient;
#endregion Protected Fields
#region Public Fields
/// <summary>
@@ -89,28 +43,6 @@ namespace SteamWare.IO
#endregion Public Fields
#region Protected Constructors
private static NLog.Logger Log = LogManager.GetCurrentClassLogger();
/// <summary>
/// classe gestione accessi a Session, cache, viewstate, configuration...
/// </summary>
protected memLayer()
{
if (Log == null)
{
Log = LogManager.GetCurrentClassLogger();
}
// istanzia il conf setting reader...
configAppSetReader = new AppSettingsReader();
// avvio e configuro TA
initTA();
setupConnectionStringBase();
setupMongo();
}
#endregion Protected Constructors
#region Public Enums
/// <summary>
@@ -141,59 +73,6 @@ namespace SteamWare.IO
#endregion Public Enums
#region Private Properties
/// <summary>
/// Oggetto currentDb locale
/// </summary>
private IDatabase _currDB { get; set; }
#endregion Private Properties
#region Protected Properties
/// <summary>
/// stringa conn x DB CONF
/// </summary>
protected string connStringDbConf
{
get
{
string answ = "";
answ = confReadString("DbConfConnectionString");
// se fosse vuota fallback a path dei permessi...
if (string.IsNullOrEmpty(answ))
{
answ = confReadString("PermessiConnectionString");
}
// se ancora vuota --> devAuth
if (string.IsNullOrEmpty(answ))
{
answ = confReadString("DevicesAuthConnectionString");
}
return answ;
}
}
/// <summary>
/// Stringa di connessione mongoDb
/// </summary>
protected string mongoConnString
{
get
{
string answ = "";
answ = confReadString("mdbConnString");
if (string.IsNullOrEmpty(answ))
{
answ = "mongodb://W2019-MONGODB:27017";
}
return answ;
}
}
#endregion Protected Properties
#region Public Properties
/// <summary>
@@ -358,7 +237,8 @@ namespace SteamWare.IO
}
/// <summary>
/// Verifica se si debba serializzare ogni valore complesso (tabelle/righe) in sessione (per impiego di sessioni avanzate come Redis)
/// Verifica se si debba serializzare ogni valore complesso (tabelle/righe) in sessione (per
/// impiego di sessioni avanzate come Redis)
/// </summary>
public bool serializeSession
{
@@ -427,162 +307,6 @@ namespace SteamWare.IO
#endregion Public Properties
#region Private Methods
/// <summary>
/// Effettua comaprazione x CHIAVE in KVP ASC
/// </summary>
/// <param name="x"></param>
/// <param name="y"></param>
/// <returns></returns>
private int CompareKey(KeyValuePair<string, int> x, KeyValuePair<string, int> y)
{
return x.Key.CompareTo(y.Key);
}
/// <summary>
/// Effettua comaprazione x CHIAVE in KVP DESC
/// </summary>
/// <param name="x"></param>
/// <param name="y"></param>
/// <returns></returns>
private int CompareKeyDesc(KeyValuePair<string, int> x, KeyValuePair<string, int> y)
{
return y.Key.CompareTo(x.Key);
}
/// <summary>
/// Init accesso MongoDb
/// </summary>
private void setupMongo()
{
currMongoClient = new MongoClient(mongoConnString);
}
#endregion Private Methods
#region Protected Methods
/// <summary>
/// init dei table adapters
/// </summary>
protected void initTA()
{
taConfig = new DS_UtilityTableAdapters.ConfigTableAdapter();
taConfigTmp = new DS_UtilityTableAdapters.ConfigTmpTableAdapter();
}
/// <summary>
/// carica in ram oggetto AppConf
/// </summary>
/// <returns></returns>
protected Dictionary<string, string> ricaricaAppConf()
{
Dictionary<string, string> answ = new Dictionary<string, string>();
// istanzio un NUOVO oggetto x evitare problemi init contestuali
memLayer nML = new memLayer();
DS_Utility.ConfigDataTable tabDati = null;
int waitMs = 100;
int numTry = 5;
do
{
try
{
tabDati = nML.taConfig.GetData();
}
catch (Exception exc)
{
numTry--;
Log.Error($"Errore procedura nML.taConfig.GetData(), numTry = {numTry}, now {waitMs}ms wait{Environment.NewLine}{exc}");
Thread.Sleep(waitMs);
}
} while (numTry > 0 && tabDati == null);
if (tabDati != null)
{
// carico
foreach (DS_Utility.ConfigRow riga in tabDati)
{
try
{
answ.Add(riga.chiave, riga.valore);
}
catch (Exception exc)
{
Log.Error(string.Format("Errore procedura ricaricaAppConf per kvp: {0} / {1}{2}{3}", riga.chiave, riga.valore, Environment.NewLine, exc));
}
}
// log ricarica
Log.Info(string.Format("Effettuata procedura ricaricaAppConf per {0} records", answ.Count));
}
return answ;
}
/// <summary>
/// effettua setup dei connection strings da web.config delal singola applicazione
/// </summary>
protected virtual void setupConnectionStringBase()
{
// connections del db
taConfig.Connection.ConnectionString = connStringDbConf;
taConfigTmp.Connection.ConnectionString = connStringDbConf;
}
/// <summary>
/// avvio oggetto AppConf in ram
/// </summary>
protected void startupAppConf()
{
// SOLO SE ho la chiave x abilitare config su DB...
if (confReadString("DbConfConnectionString") != "")
{
try
{
if (redKeyPresent(ACBH))
{
AppConf = new Dictionary<string, string>();
foreach (var item in redGetHash(ACBH))
{
if (AppConf.ContainsKey(item.Key))
{
AppConf[item.Key] = item.Value;
}
else
{
AppConf.Add(item.Key, item.Value);
}
}
}
else
{
AppConf = ricaricaAppConf();
if (AppConf.Count > 0)
{
KeyValuePair<string, string>[] valori = new KeyValuePair<string, string>[AppConf.Count];
int i = 0;
foreach (var item in AppConf)
{
valori[i] = new KeyValuePair<string, string>(item.Key, item.Value);
i++;
}
// salvo in redis valori (con TTL)
redSaveHash(ACBH, valori, maxAgeAppConf);
Log.Info("Completato procedura startupAppConf");
}
else
{
Log.Error("Errore in procedura startupAppConf, ritornato insieme vuoto");
}
}
}
catch (Exception exc)
{
Log.Error(string.Format("Errore in startupAppConf:{0}{1}", Environment.NewLine, exc));
}
}
}
#endregion Protected Methods
#region Public Methods
/// <summary>
@@ -596,12 +320,13 @@ namespace SteamWare.IO
}
/// <summary>
/// aggiunge la stringa corrente nel dictionary delle tabelle messe in cache e da aggiornare su comando update
/// aggiunge la stringa corrente nel dictionary delle tabelle messe in cache e da aggiornare
/// su comando update
/// </summary>
/// <param name="nuovaTab"></param>
public void addTabInCache(string nuovaTab)
{
// provo ad aggiungere nuova tab in elenco...
// provo ad aggiungere nuova tab in elenco...
Dictionary<string, string> _tabelleInCache = tabelleInCache;
try
{
@@ -613,13 +338,14 @@ namespace SteamWare.IO
}
/// <summary>
/// aggiunge la stringa corrente nel dictionary delle tabelle messe in session che vanno preservate da comando update (es: oggetto selezionato...)
/// aggiunge la stringa corrente nel dictionary delle tabelle messe in session che vanno
/// preservate da comando update (es: oggetto selezionato...)
/// </summary>
/// <param name="nomePar"></param>
/// <param name="valore"></param>
public void addValInSession(string nomePar, string valore)
{
// provo ad aggiungere nuova tab in elenco...
// provo ad aggiungere nuova tab in elenco...
Dictionary<string, string> _valoriInSession2Survive = valSess2SurvUpd;
// verifico se fare update o insert...
if (_valoriInSession2Survive.ContainsKey(nomePar))
@@ -1482,8 +1208,7 @@ namespace SteamWare.IO
public int redCountKey(string keyPattern)
{
int answ = 0;
// cerco se ci sia valore in redis...
// se vuoto = ALL...
// cerco se ci sia valore in redis... se vuoto = ALL...
keyPattern = string.IsNullOrEmpty(keyPattern) ? "**" : keyPattern;
try
{
@@ -1503,6 +1228,29 @@ namespace SteamWare.IO
return answ;
}
/// <summary>
/// ELIMINA un SINGOLO VALORE dalla hash (dato field = chiave)
/// </summary>
/// <param name="hashKey"></param>
/// <param name="hashField"></param>
/// <returns></returns>
public bool redDelHashField(string hashKey, string hashField)
{
bool answ = false;
// cerco se ci sia valore in redis...
try
{
RedisKey chiave = hashKey;
RedisValue campo = hashField;
answ = cache.HashDelete(chiave, campo);
}
catch (Exception exc)
{
Log.Error($"Errore in redDelHashField{Environment.NewLine}{exc}");
}
return answ;
}
/// <summary>
/// Elimina una key (hash, string)
/// </summary>
@@ -1531,8 +1279,7 @@ namespace SteamWare.IO
public bool redFlushKey(string keyPattern)
{
bool answ = false;
// cerco se ci sia valore in redis...
// se vuoto = ALL...
// cerco se ci sia valore in redis... se vuoto = ALL...
keyPattern = string.IsNullOrEmpty(keyPattern) ? "**" : keyPattern;
try
{
@@ -1697,7 +1444,8 @@ namespace SteamWare.IO
}
/// <summary>
/// Nome della variabile HASH da utilizzare (dato CodModulo / Server / DB impiegato da funzionalita' DbConfig) + keyName richiesto...
/// Nome della variabile HASH da utilizzare (dato CodModulo / Server / DB impiegato da
/// funzionalita' DbConfig) + keyName richiesto...
/// </summary>
public string redHash(string keyName)
{
@@ -1820,7 +1568,9 @@ namespace SteamWare.IO
/// </summary>
/// <param name="hashKey">chiave</param>
/// <param name="hashFields">valori</param>
/// <param name="expireSeconds">scadenza preimpostata hash (secondi) | defaoult = -1 (non scade)</param>
/// <param name="expireSeconds">
/// scadenza preimpostata hash (secondi) | defaoult = -1 (non scade)
/// </param>
/// <returns></returns>
public bool redSaveHash(string hashKey, KeyValuePair<string, string>[] hashFields, double expireSeconds = -1)
{
@@ -1874,7 +1624,9 @@ namespace SteamWare.IO
/// </summary>
/// <param name="hashKey">chiave</param>
/// <param name="hashFields">valori</param>
/// <param name="expireSeconds">scadenza preimpostata hash (secondi) | defaoult = -1 (non scade)</param>
/// <param name="expireSeconds">
/// scadenza preimpostata hash (secondi) | defaoult = -1 (non scade)
/// </param>
/// <returns></returns>
public bool redSaveHashDict(string hashKey, Dictionary<string, string> hashFields, double expireSeconds = -1)
{
@@ -2123,7 +1875,7 @@ namespace SteamWare.IO
}
/// <summary>
/// Salva un set KVP (Key Value Pair) in RedisCache
/// Salva un set KVP (Key Value Pair) in RedisCache
/// </summary>
/// <param name="valori">Set KVP chiave-valore da salvare</param>
/// <returns></returns>
@@ -2217,7 +1969,9 @@ namespace SteamWare.IO
/// </summary>
/// <param name="nome">nome della variabile</param>
/// <param name="dSet">DataSet da salvare</param>
/// <param name="surviveUpdate">indica se debba sopravvivere ad update (inserita in elenco valSess2SurvUpd)</param>
/// <param name="surviveUpdate">
/// indica se debba sopravvivere ad update (inserita in elenco valSess2SurvUpd)
/// </param>
/// <returns></returns>
public bool setSessionDataSet(string nome, DataSet dSet, bool surviveUpdate)
{
@@ -2257,7 +2011,9 @@ namespace SteamWare.IO
/// </summary>
/// <param name="nome">nome della variabile</param>
/// <param name="dTable">DataTable da salvare</param>
/// <param name="surviveUpdate">indica se debba sopravvivere ad update (inserita in elenco valSess2SurvUpd)</param>
/// <param name="surviveUpdate">
/// indica se debba sopravvivere ad update (inserita in elenco valSess2SurvUpd)
/// </param>
public bool setSessionDataTable(string nome, DataTable dTable, bool surviveUpdate)
{
bool _done = false;
@@ -2296,7 +2052,9 @@ namespace SteamWare.IO
/// </summary>
/// <param name="nome">nome della variabile</param>
/// <param name="valore">valore associato</param>
/// <param name="surviveUpdate">indica se debba sopravvivere ad update (inserita in elenco valSess2SurvUpd)</param>
/// <param name="surviveUpdate">
/// indica se debba sopravvivere ad update (inserita in elenco valSess2SurvUpd)
/// </param>
/// <returns></returns>
public bool setSessionVal(string nome, object valore, bool surviveUpdate)
{
@@ -2363,5 +2121,283 @@ namespace SteamWare.IO
}
#endregion Public Methods
#region Protected Fields
/// <summary>
/// lettore file configurazione
/// </summary>
protected AppSettingsReader configAppSetReader;
/// <summary>
/// Oggetto MongoDbCLient x accesso al motore
/// </summary>
protected MongoClient currMongoClient;
#endregion Protected Fields
#region Protected Constructors
/// <summary>
/// classe gestione accessi a Session, cache, viewstate, configuration...
/// </summary>
protected memLayer()
{
if (Log == null)
{
Log = LogManager.GetCurrentClassLogger();
}
// istanzia il conf setting reader...
configAppSetReader = new AppSettingsReader();
// avvio e configuro TA
initTA();
setupConnectionStringBase();
setupMongo();
}
#endregion Protected Constructors
#region Protected Properties
/// <summary>
/// stringa conn x DB CONF
/// </summary>
protected string connStringDbConf
{
get
{
string answ = "";
answ = confReadString("DbConfConnectionString");
// se fosse vuota fallback a path dei permessi...
if (string.IsNullOrEmpty(answ))
{
answ = confReadString("PermessiConnectionString");
}
// se ancora vuota --> devAuth
if (string.IsNullOrEmpty(answ))
{
answ = confReadString("DevicesAuthConnectionString");
}
return answ;
}
}
/// <summary>
/// Stringa di connessione mongoDb
/// </summary>
protected string mongoConnString
{
get
{
string answ = "";
answ = confReadString("mdbConnString");
if (string.IsNullOrEmpty(answ))
{
answ = "mongodb://W2019-MONGODB:27017";
}
return answ;
}
}
#endregion Protected Properties
#region Protected Methods
/// <summary>
/// init dei table adapters
/// </summary>
protected void initTA()
{
taConfig = new DS_UtilityTableAdapters.ConfigTableAdapter();
taConfigTmp = new DS_UtilityTableAdapters.ConfigTmpTableAdapter();
}
/// <summary>
/// carica in ram oggetto AppConf
/// </summary>
/// <returns></returns>
protected Dictionary<string, string> ricaricaAppConf()
{
Dictionary<string, string> answ = new Dictionary<string, string>();
// istanzio un NUOVO oggetto x evitare problemi init contestuali
memLayer nML = new memLayer();
DS_Utility.ConfigDataTable tabDati = null;
int waitMs = 100;
int numTry = 5;
do
{
try
{
tabDati = nML.taConfig.GetData();
}
catch (Exception exc)
{
numTry--;
Log.Error($"Errore procedura nML.taConfig.GetData(), numTry = {numTry}, now {waitMs}ms wait{Environment.NewLine}{exc}");
Thread.Sleep(waitMs);
}
} while (numTry > 0 && tabDati == null);
if (tabDati != null)
{
// carico
foreach (DS_Utility.ConfigRow riga in tabDati)
{
try
{
answ.Add(riga.chiave, riga.valore);
}
catch (Exception exc)
{
Log.Error(string.Format("Errore procedura ricaricaAppConf per kvp: {0} / {1}{2}{3}", riga.chiave, riga.valore, Environment.NewLine, exc));
}
}
// log ricarica
Log.Info(string.Format("Effettuata procedura ricaricaAppConf per {0} records", answ.Count));
}
return answ;
}
/// <summary>
/// effettua setup dei connection strings da web.config delal singola applicazione
/// </summary>
protected virtual void setupConnectionStringBase()
{
// connections del db
taConfig.Connection.ConnectionString = connStringDbConf;
taConfigTmp.Connection.ConnectionString = connStringDbConf;
}
/// <summary>
/// avvio oggetto AppConf in ram
/// </summary>
protected void startupAppConf()
{
// SOLO SE ho la chiave x abilitare config su DB...
if (confReadString("DbConfConnectionString") != "")
{
try
{
if (redKeyPresent(ACBH))
{
AppConf = new Dictionary<string, string>();
foreach (var item in redGetHash(ACBH))
{
if (AppConf.ContainsKey(item.Key))
{
AppConf[item.Key] = item.Value;
}
else
{
AppConf.Add(item.Key, item.Value);
}
}
}
else
{
AppConf = ricaricaAppConf();
if (AppConf.Count > 0)
{
KeyValuePair<string, string>[] valori = new KeyValuePair<string, string>[AppConf.Count];
int i = 0;
foreach (var item in AppConf)
{
valori[i] = new KeyValuePair<string, string>(item.Key, item.Value);
i++;
}
// salvo in redis valori (con TTL)
redSaveHash(ACBH, valori, maxAgeAppConf);
Log.Info("Completato procedura startupAppConf");
}
else
{
Log.Error("Errore in procedura startupAppConf, ritornato insieme vuoto");
}
}
}
catch (Exception exc)
{
Log.Error(string.Format("Errore in startupAppConf:{0}{1}", Environment.NewLine, exc));
}
}
}
#endregion Protected Methods
#region Private Fields
private static NLog.Logger Log = LogManager.GetCurrentClassLogger();
/// <summary>
/// Connessione lazy a redis...
/// </summary>
private Lazy<ConnectionMultiplexer> lazyConnection = new Lazy<ConnectionMultiplexer>(() =>
{
string RedisConn = memLayer.ML.confReadString("RedisConn");
if (string.IsNullOrEmpty(RedisConn))
{
RedisConn = "localhost,abortConnect=false,ssl=false";
}
return ConnectionMultiplexer.Connect(RedisConn);
});
/// <summary>
/// Connessione lazy a redis...
/// </summary>
private Lazy<ConnectionMultiplexer> lazyConnectionAdmin = new Lazy<ConnectionMultiplexer>(() =>
{
string RedisConnAdmin = memLayer.ML.confReadString("RedisConnAdmin");
if (string.IsNullOrEmpty(RedisConnAdmin))
{
RedisConnAdmin = "localhost,abortConnect=false,ssl=false,allowAdmin=true";
}
return ConnectionMultiplexer.Connect(RedisConnAdmin);
});
#endregion Private Fields
#region Private Properties
/// <summary>
/// Oggetto currentDb locale
/// </summary>
private IDatabase _currDB { get; set; }
#endregion Private Properties
#region Private Methods
/// <summary>
/// Effettua comaprazione x CHIAVE in KVP ASC
/// </summary>
/// <param name="x"></param>
/// <param name="y"></param>
/// <returns></returns>
private int CompareKey(KeyValuePair<string, int> x, KeyValuePair<string, int> y)
{
return x.Key.CompareTo(y.Key);
}
/// <summary>
/// Effettua comaprazione x CHIAVE in KVP DESC
/// </summary>
/// <param name="x"></param>
/// <param name="y"></param>
/// <returns></returns>
private int CompareKeyDesc(KeyValuePair<string, int> x, KeyValuePair<string, int> y)
{
return y.Key.CompareTo(x.Key);
}
/// <summary>
/// Init accesso MongoDb
/// </summary>
private void setupMongo()
{
currMongoClient = new MongoClient(mongoConnString);
}
#endregion Private Methods
}
}
+23
View File
@@ -1245,6 +1245,29 @@ namespace SteamWare
return answ;
}
/// <summary>
/// ELIMINA un SINGOLO VALORE dalla hash (dato field = chiave)
/// </summary>
/// <param name="hashKey"></param>
/// <param name="hashField"></param>
/// <returns></returns>
public bool redDelHashField(string hashKey, string hashField)
{
bool answ = false;
// cerco se ci sia valore in redis...
try
{
RedisKey chiave = hashKey;
RedisValue campo = hashField;
answ = cache.HashDelete(chiave, campo);
}
catch (Exception exc)
{
Log.Error($"Errore in redDelHashField{Environment.NewLine}{exc}");
}
return answ;
}
/// <summary>
/// Elimina una key (hash, string)
/// </summary>