Inizio sistemazione cache redis x utenti
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<item>
|
||||
<version>0.9.2305.2617</version>
|
||||
<url>http://nexus.steamware.net/repository/SWS/WDC/stable/WDC.UI.zip</url>
|
||||
<url>http://nexus.steamware.net/repository/SWS/WDC/stable/WDC.API.zip</url>
|
||||
<changelog>http://nexus.steamware.net/repository/SWS/WDC/stable/ChangeLog.html</changelog>
|
||||
<mandatory>false</mandatory>
|
||||
</item>
|
||||
|
||||
@@ -49,6 +49,7 @@ namespace WebDoorCreator.Core
|
||||
public const string rKeyOrderStatus = $"{redisBaseAddr}:Cache:OrderStatus";
|
||||
public const string rKeyRoles = $"{redisBaseAddr}:Cache:Roles";
|
||||
public const string rKeyUsers = $"{redisBaseAddr}:Cache:Users";
|
||||
public const string rKeyUsersAll = $"{redisBaseAddr}:Cache:UsersAll";
|
||||
public const string rKeyUsersView = $"{redisBaseAddr}:Cache:UsersView";
|
||||
public const string rKeyVocLemma = $"{redisBaseAddr}:Cache:VocLemma";
|
||||
public const string rKeyLanguage = $"{redisBaseAddr}:Cache:Languages";
|
||||
|
||||
@@ -2280,12 +2280,6 @@ namespace WebDoorCreator.Data.Services
|
||||
|
||||
#endregion Public Methods
|
||||
|
||||
#region Protected Fields
|
||||
|
||||
protected Random rnd = new Random();
|
||||
|
||||
#endregion Protected Fields
|
||||
|
||||
#region Protected Properties
|
||||
|
||||
protected WebDoorCreator.Data.DDF.Converter currDdfConv { get; set; } = null!;
|
||||
@@ -2295,11 +2289,8 @@ namespace WebDoorCreator.Data.Services
|
||||
#region Private Fields
|
||||
|
||||
private static IConfiguration _configuration = null!;
|
||||
|
||||
private static JsonSerializerSettings? JSSettings;
|
||||
|
||||
private static Logger Log = LogManager.GetCurrentClassLogger();
|
||||
|
||||
private readonly IEmailSender _emailSender;
|
||||
|
||||
/// <summary>
|
||||
@@ -2322,6 +2313,8 @@ namespace WebDoorCreator.Data.Services
|
||||
/// </summary>
|
||||
private IDatabase redisDb = null!;
|
||||
|
||||
private Random rnd = new Random();
|
||||
|
||||
#endregion Private Fields
|
||||
|
||||
#region Private Properties
|
||||
|
||||
@@ -1,4 +1,14 @@
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Newtonsoft.Json;
|
||||
using NLog;
|
||||
using NLog.Fluent;
|
||||
using Org.BouncyCastle.Asn1.X500;
|
||||
using StackExchange.Redis;
|
||||
using System.Diagnostics;
|
||||
using WebDoorCreator.Core;
|
||||
using WebDoorCreator.Data.DbModels;
|
||||
using WebDoorCreator.Data.User;
|
||||
|
||||
namespace WebDoorCreator.UI.Data
|
||||
@@ -7,9 +17,102 @@ namespace WebDoorCreator.UI.Data
|
||||
{
|
||||
#region Public Constructors
|
||||
|
||||
public WDCUserService(UserManager<IdentityUser> userManager)
|
||||
private static Logger Log = LogManager.GetCurrentClassLogger();
|
||||
/// <summary>
|
||||
/// Durata cache lunga IN SECONDI
|
||||
/// </summary>
|
||||
private int cacheTtlLong = 60 * 5;
|
||||
|
||||
/// <summary>
|
||||
/// Durata cache breve IN SECONDI
|
||||
/// </summary>
|
||||
private int cacheTtlShort = 60 * 1;
|
||||
|
||||
/// <summary>
|
||||
/// Oggetto per connessione a REDIS
|
||||
/// </summary>
|
||||
private IConnectionMultiplexer redisConn;
|
||||
|
||||
/// <summary>
|
||||
/// Oggetto DB redis da impiegare x chiamate R/W
|
||||
/// </summary>
|
||||
private IDatabase redisDb = null!;
|
||||
|
||||
private static JsonSerializerSettings? JSSettings;
|
||||
/// <summary>
|
||||
/// Durata cache breve (1 min circa + perturbazione percentuale +/-10%)
|
||||
/// </summary>
|
||||
private TimeSpan FastCache
|
||||
{
|
||||
get => TimeSpan.FromSeconds(cacheTtlShort * rnd.Next(900, 1100) / 1000);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Durata cache lunga (+ perturbazione percentuale +/-10%)
|
||||
/// </summary>
|
||||
private TimeSpan LongCache
|
||||
{
|
||||
get => TimeSpan.FromSeconds(cacheTtlLong * rnd.Next(900, 1100) / 1000);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Durata cache molto breve (10 sec circa + perturbazione percentuale +/-10%)
|
||||
/// </summary>
|
||||
private TimeSpan UltraFastCache
|
||||
{
|
||||
get => TimeSpan.FromSeconds(cacheTtlShort / 6 * rnd.Next(900, 1100) / 1000);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Durata cache lunga (+ perturbazione percentuale +/-10%)
|
||||
/// </summary>
|
||||
private TimeSpan UltraLongCache
|
||||
{
|
||||
get => TimeSpan.FromSeconds(cacheTtlLong * 10 * rnd.Next(900, 1100) / 1000);
|
||||
}
|
||||
private Random rnd = new Random();
|
||||
|
||||
/// <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;
|
||||
}
|
||||
}
|
||||
|
||||
return answ;
|
||||
}
|
||||
|
||||
public WDCUserService(IConnectionMultiplexer redisConnMult, UserManager<IdentityUser> userManager)
|
||||
{
|
||||
_userManager = userManager;
|
||||
// Conf cache
|
||||
redisConn = redisConnMult;
|
||||
redisDb = this.redisConn.GetDatabase();
|
||||
|
||||
// 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
|
||||
};
|
||||
// chiudo log
|
||||
Log.Info("Avviata classe WDCUserService");
|
||||
}
|
||||
|
||||
#endregion Public Constructors
|
||||
@@ -102,7 +205,51 @@ namespace WebDoorCreator.UI.Data
|
||||
#region Public Methods
|
||||
|
||||
/// <summary>
|
||||
/// Dati utente (filtrati da searchVal)
|
||||
/// Dati utente (TUTTI) da REDIS o DB
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public async Task<List<IdentityUser>> UserDataGetAll()
|
||||
{
|
||||
string source = "DB";
|
||||
|
||||
List<IdentityUser> dbResult = new List<IdentityUser>();
|
||||
// cerco da cache
|
||||
string currKey = $"{Constants.rKeyUsersAll}";
|
||||
Stopwatch stopWatch = new Stopwatch();
|
||||
stopWatch.Start();
|
||||
string? rawData = await redisDb.StringGetAsync(currKey);
|
||||
if (!string.IsNullOrEmpty(rawData))
|
||||
{
|
||||
source = "REDIS";
|
||||
var tempResult = JsonConvert.DeserializeObject<List<IdentityUser>>(rawData);
|
||||
if (tempResult == null)
|
||||
{
|
||||
dbResult = new List<IdentityUser>();
|
||||
}
|
||||
else
|
||||
{
|
||||
dbResult = tempResult;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
dbResult = await _userManager.Users.ToListAsync();
|
||||
rawData = JsonConvert.SerializeObject(dbResult, JSSettings);
|
||||
await redisDb.StringSetAsync(currKey, rawData, LongCache);
|
||||
}
|
||||
if (dbResult == null)
|
||||
{
|
||||
dbResult = new List<IdentityUser>();
|
||||
}
|
||||
stopWatch.Stop();
|
||||
TimeSpan ts = stopWatch.Elapsed;
|
||||
Log.Debug($"UserDataGetAll | {source} in: {ts.TotalMilliseconds} ms");
|
||||
return dbResult;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Dati utente (filtrati da UserId)
|
||||
/// </summary>
|
||||
/// <param name="searchVal"></param>
|
||||
/// <returns></returns>
|
||||
@@ -111,8 +258,11 @@ namespace WebDoorCreator.UI.Data
|
||||
// Collezione utenti
|
||||
List<IdentityUser> RawList = new List<IdentityUser>();
|
||||
List<UserData> UsersList = new List<UserData>();
|
||||
#if false
|
||||
// recupero utenti da obj _userManager
|
||||
var allData = _userManager.Users.ToList();
|
||||
var allData = _userManager.Users.ToList();
|
||||
#endif
|
||||
var allData = await UserDataGetAll();
|
||||
if (!string.IsNullOrEmpty(searchVal))
|
||||
{
|
||||
RawList = allData.Where(x => x.NormalizedEmail.Contains(searchVal.ToUpper()) || x.NormalizedUserName.Contains(searchVal.ToUpper())).ToList();
|
||||
@@ -147,6 +297,52 @@ namespace WebDoorCreator.UI.Data
|
||||
return await Task.FromResult(UsersList);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Dati utente (singolo x UserId)
|
||||
/// </summary>
|
||||
/// <param name="UserId"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<List<UserData>> UserDataGetById(string UserId)
|
||||
{
|
||||
// Collezione utenti
|
||||
List<IdentityUser> RawList = new List<IdentityUser>();
|
||||
List<UserData> UsersList = new List<UserData>();
|
||||
// recupero utenti da obj _userManager
|
||||
var allData = _userManager.Users.ToList();
|
||||
if (!string.IsNullOrEmpty(UserId))
|
||||
{
|
||||
RawList = allData.Where(x => x.NormalizedEmail.Contains(UserId.ToUpper()) || x.NormalizedUserName.Contains(UserId.ToUpper())).ToList();
|
||||
}
|
||||
else
|
||||
{
|
||||
RawList = allData;
|
||||
}
|
||||
var user = RawList.Select(x => new IdentityUser
|
||||
{
|
||||
Id = x.Id,
|
||||
UserName = x.UserName,
|
||||
Email = x.Email,
|
||||
PhoneNumber = x.PhoneNumber,
|
||||
PasswordHash = "*****",
|
||||
EmailConfirmed = x.EmailConfirmed
|
||||
}).ToList();
|
||||
|
||||
foreach (var item in user)
|
||||
{
|
||||
var UserRoles = await _userManager.GetRolesAsync(item);
|
||||
var UserClaims = await _userManager.GetClaimsAsync(item);
|
||||
|
||||
var newItem = new UserData()
|
||||
{
|
||||
Identity = item,
|
||||
Roles = UserRoles.ToList(),
|
||||
Claims = UserClaims.ToList()
|
||||
};
|
||||
UsersList.Add(newItem);
|
||||
}
|
||||
return await Task.FromResult(UsersList);
|
||||
}
|
||||
|
||||
#endregion Public Methods
|
||||
|
||||
#region Protected Methods
|
||||
|
||||
Reference in New Issue
Block a user