Inizio migrazione redis cache

This commit is contained in:
Samuele Locatelli
2024-04-03 09:10:26 +02:00
parent a6656f1ba0
commit ca46bb9f04
10 changed files with 255 additions and 56 deletions
+171 -5
View File
@@ -2,8 +2,13 @@
using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using MP.Data.Controllers;
using MP.Data.DatabaseModels;
using MP.Data.Services;
using Newtonsoft.Json;
using NLog;
using NLog.Fluent;
using StackExchange.Redis;
using System;
using System.Collections.Generic;
using System.Data;
@@ -15,20 +20,34 @@ using static MP.Data.Objects.Enums;
namespace MP.Stats.Data
{
public class MpStatsService : IDisposable
public class MpStatsService : BaseServ, IDisposable
{
#region Public Fields
public static MP.Data.Controllers.MpStatsController dbController;
#endregion Public Fields
/// <summary>
/// Oggetto per connessione a REDIS
/// </summary>
protected ConnectionMultiplexer redisConn = null!;
/// <summary>
/// Oggetto DB redis da impiegare x chiamate R/W
/// </summary>
protected IDatabase redisDb = null!;
#region Public Constructors
public MpStatsService(IConfiguration configuration, ILogger<MpStatsService> logger, IMemoryCache memoryCache, IDistributedCache distributedCache)
{
_logger = logger;
_configuration = configuration;
// setup compoenti REDIS
redisConn = ConnectionMultiplexer.Connect(_configuration.GetConnectionString("Redis"));
redisDb = redisConn.GetDatabase();
// conf cache
this.memoryCache = memoryCache;
this.distributedCache = distributedCache;
@@ -136,6 +155,54 @@ namespace MP.Stats.Data
{
// Clear database controller
dbController.Dispose();
// redis dispose
redisConn = null;
redisDb = null;
}
/// <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);
}
answ = true;
}
}
// notifico update ai client in ascolto x reset cache
NotifyReloadRequest($"FlushRedisCache | {pattern}");
return answ;
}
/// <summary>
/// Evento richiesta rilettura dati pagina (x refresh pagine aperte)
/// </summary>
public event EventHandler ReloadRequest = delegate { };
/// <summary>
/// Invio notifica rilettura (con parametro)
/// </summary>
/// <param name="message"></param>
public void NotifyReloadRequest(string message)
{
if (ReloadRequest != null)
{
// messaggio
ReloadEventArgs rea = new ReloadEventArgs(message);
ReloadRequest.Invoke(this, rea);
}
}
/// <summary>
@@ -147,10 +214,14 @@ namespace MP.Stats.Data
{
TaskResultModel dbResult = dbController.ExecuteTask(TaskId);
// svuoto cache!
await FlushCache("TaskList");
await FlushCache("TaskExecList");
#if false
string cacheKey = $"MP:STATS:TaskList";
await distributedCache.RemoveAsync(cacheKey);
cacheKey = $"MP:STATS:TaskExecList";
await distributedCache.RemoveAsync(cacheKey);
await distributedCache.RemoveAsync(cacheKey);
#endif
return await Task.FromResult(dbResult);
}
@@ -443,6 +514,8 @@ namespace MP.Stats.Data
return await Task.FromResult(dbResult);
}
private string redisBaseKey = "MP:STATS";
/// <summary>
/// Ricerca task dato tipo + num max (desc)
/// </summary>
@@ -450,6 +523,35 @@ namespace MP.Stats.Data
/// <returns></returns>
public async Task<List<TaskExecModel>> TaskExecGetFilt(int TaskId, int maxRec, string searchVal)
{
// setup parametri costanti
string source = "DB";
Stopwatch sw = new Stopwatch();
sw.Start();
List<TaskExecModel> result = new List<TaskExecModel>();
// cerco in redis...
DateTime adesso = DateTime.Now;
string currKey = $"{redisBaseKey}:TaskExecList:{TaskId}:{adesso:yyMMdd}:{adesso:HHmm}:{maxRec}";
RedisValue rawData = await redisDb.StringGetAsync(currKey);
if (rawData.HasValue)
{
result = JsonConvert.DeserializeObject<List<TaskExecModel>>($"{rawData}");
source = "REDIS";
}
else
{
result = dbController.TaskExecGetFilt(TaskId, maxRec);
// serializzp e salvo...
rawData = JsonConvert.SerializeObject(result);
await redisDb.StringSetAsync(currKey, rawData, FastCache);
}
if (result == null)
{
result = new List<TaskExecModel>();
}
sw.Stop();
_logger.LogDebug($"TaskExecGetFilt | {source} | {sw.Elapsed.TotalMilliseconds}ms");
return result;
#if false
List<TaskExecModel> dbResult = new List<TaskExecModel>();
DateTime adesso = DateTime.Now;
string cacheKey = $"MP:STATS:TaskExecList:{TaskId}:{adesso:yyMMdd}:{adesso:HHmm}:{maxRec}";
@@ -479,7 +581,8 @@ namespace MP.Stats.Data
.Where(x => x.Result.Contains(searchVal, StringComparison.InvariantCultureIgnoreCase))
.ToList();
}
return await Task.FromResult(dbResult);
return await Task.FromResult(dbResult);
#endif
}
/// <summary>
@@ -490,6 +593,45 @@ namespace MP.Stats.Data
/// <returns></returns>
public async Task<List<TaskListModel>> TaskListAll(Task2ExeType TType, string searchVal = "")
{
// setup parametri costanti
string source = "DB";
Stopwatch sw = new Stopwatch();
sw.Start();
List<TaskListModel> result = new List<TaskListModel>();
// cerco in redis...
DateTime adesso = DateTime.Now;
string currKey = $"{redisBaseKey}:TaskList:{TType}";
RedisValue rawData = await redisDb.StringGetAsync(currKey);
if (rawData.HasValue)
{
result = JsonConvert.DeserializeObject<List<TaskListModel>>($"{rawData}");
source = "REDIS";
}
else
{
result = dbController.TaskListGetAll(TType);
// serializzp e salvo...
rawData = JsonConvert.SerializeObject(result);
await redisDb.StringSetAsync(currKey, rawData, FastCache);
}
if (result == null)
{
result = new List<TaskListModel>();
}
// se necessario filtro..
if (!string.IsNullOrEmpty(searchVal))
{
result = result
.Where(x => x.Name.Contains(searchVal, StringComparison.InvariantCultureIgnoreCase)
|| x.Descript.Contains(searchVal, StringComparison.InvariantCultureIgnoreCase))
.ToList();
}
sw.Stop();
_logger.LogDebug($"TaskListAll | {source} | {sw.Elapsed.TotalMilliseconds}ms");
return result;
#if false
List<TaskListModel> dbResult = new List<TaskListModel>();
string cacheKey = $"MP:STATS:TaskList:{TType}";
string rawData;
@@ -519,9 +661,30 @@ namespace MP.Stats.Data
|| x.Descript.Contains(searchVal, StringComparison.InvariantCultureIgnoreCase))
.ToList();
}
return await Task.FromResult(dbResult);
return await Task.FromResult(dbResult);
#endif
}
/// <summary>
/// Pulizia cache Redis (tutta)
/// </summary>
/// <returns></returns>
public async Task<bool> FlushCache()
{
RedisValue pattern = new RedisValue($"{redisBaseKey}:*");
bool answ = await ExecFlushRedisPattern(pattern);
return answ;
}
/// <summary>
/// Pulizia cache Redis per chiave specifica (da redisBaseKey...)
/// </summary>
/// <returns></returns>
public async Task<bool> FlushCache(string KeyReq)
{
RedisValue pattern = new RedisValue($"{redisBaseKey}:{KeyReq}:*");
bool answ = await ExecFlushRedisPattern(pattern);
return answ;
}
/// <summary>
/// Update/Insert record TaskList
/// </summary>
@@ -531,10 +694,13 @@ namespace MP.Stats.Data
{
bool dbResult = dbController.TaskListUpsert(rec2upd);
// svuoto cache!
await FlushCache("TaskList");
#if false
string cacheKey = $"MP:STATS:TaskList:{rec2upd.TType}";
await distributedCache.RemoveAsync(cacheKey);
cacheKey = $"MP:STATS:TaskList:ND";
await distributedCache.RemoveAsync(cacheKey);
await distributedCache.RemoveAsync(cacheKey);
#endif
return await Task.FromResult(dbResult);
}