Files

173 lines
5.5 KiB
C#

using NLog;
using StackExchange.Redis;
using Microsoft.Extensions.Configuration;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MagMan.Core.Services
{
/// <summary>
/// Classe di partenza x costruzione servizi di accesso dati + cache
/// </summary>
public class BaseServ
{
#region Public Methods
/// <summary>
/// Refresh globale cache redis
/// </summary>
/// <returns></returns>
public async Task<bool> FlushRedisCache()
{
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
await Task.Delay(1);
RedisValue pattern = new RedisValue($"{Const.rKeyConfig}:*");
bool answ = await ExecFlushRedisPattern(pattern);
stopWatch.Stop();
Log.Debug($"FlushRedisCache in {stopWatch.Elapsed.TotalMilliseconds} ms");
return answ;
}
#endregion Public Methods
#region Protected Fields
protected static IConfiguration _configuration = null!;
protected static Logger Log = LogManager.GetCurrentClassLogger();
/// <summary>
/// Numero di operazioni parallele che si possono svolgere... (se 0 NON usa cicli paralleli)
/// </summary>
protected int numPar = 0;
/// <summary>
/// Oggetto per connessione a REDIS
/// </summary>
protected IConnectionMultiplexer redisConn = null!;
/// <summary>
/// Oggetto DB redis da impiegare x chiamate R/W
/// </summary>
protected IDatabase redisDb = null!;
#endregion Protected Fields
#region Protected Properties
protected string CodApp { get; set; } = "";
/// <summary>
/// Durata cache breve (1 min circa + perturbazione percentuale +/-10%)
/// </summary>
protected TimeSpan FastCache
{
get => TimeSpan.FromSeconds(cacheTtlShort * rnd.Next(900, 1100) / 1000);
}
/// <summary>
/// Durata cache lunga (+ perturbazione percentuale +/-10%)
/// </summary>
protected TimeSpan LongCache
{
get => TimeSpan.FromSeconds(cacheTtlLong * rnd.Next(900, 1100) / 1000);
}
/// <summary>
/// Durata cache MOLTO breve (10 sec circa + perturbazione percentuale +/-10%)
/// </summary>
protected TimeSpan UltraFastCache
{
get => TimeSpan.FromSeconds(cacheTtlShort / 6 * rnd.Next(900, 1100) / 1000);
}
/// <summary>
/// Durata cache MOLTO lunga (+ perturbazione percentuale +/-10%)
/// </summary>
protected TimeSpan UltraLongCache
{
get => TimeSpan.FromSeconds(cacheTtlLong * 10 * rnd.Next(900, 1100) / 1000);
}
#endregion Protected Properties
#region Protected Methods
/// <summary>
/// Esegue flush memoria redis dato pattern
/// </summary>
/// <param name="pattern"></param>
/// <returns></returns>
protected async Task<bool> ExecFlushRedisPattern(RedisValue pattern)
{
bool answ = false;
/*******************************
* Recupero elenco dei server da cui cancellare le chaivi:
* - prendo solo i server connessi
* - prendo solo NON repliche (= master)
* - me ne aspetto 1 in uscita cmq
*******************************/
var connServ = redisConn.GetEndPoints()
.Select(endpoint =>
{
var server = redisConn.GetServer(endpoint);
return server;
})
.Where(x => x.IsConnected && !x.IsReplica)
.ToList();
// ciclo (anche se me ne aspetto 1 solo)
foreach (var mServer in connServ)
{
try
{
var keyList = mServer.Keys(redisDb.Database, pattern);
if (numPar > 0)
{
var options = new ParallelOptions { MaxDegreeOfParallelism = numPar };
await Parallel.ForEachAsync(keyList, async (item, token) =>
{
// cancello
await redisDb.KeyDeleteAsync(item);
});
}
else
{
foreach (var item in keyList)
{
await redisDb.KeyDeleteAsync(item);
}
}
answ = true;
}
catch (Exception exc)
{
Log.Error($"Eccezione durante ExecFlushRedisPattern | pattern: {pattern}{Environment.NewLine}{exc}");
}
}
return answ;
}
#endregion Protected Methods
#region Private Fields
/// <summary>
/// Durata cache lunga IN SECONDI
/// </summary>
private int cacheTtlLong = 60 * 5;
/// <summary>
/// Durata cache breve IN SECONDI
/// </summary>
private int cacheTtlShort = 60 * 1;
private Random rnd = new Random();
#endregion Private Fields
}
}