Merge branch 'Release/MigrateMongoCall_01'

This commit is contained in:
Samuele Locatelli
2026-04-24 07:49:10 +02:00
21 changed files with 614 additions and 77 deletions
+25
View File
@@ -0,0 +1,25 @@
namespace MP.Core.Objects
{
public class MachDataItem
{
public enum DataItemCategory
{
CONDITION = 0,
EVENT = 1,
SAMPLE = 2
}
public string Uuid { get; set; } = "";
public DataItemCategory Category { get; set; }
public string? Name { get; set; } = "";
public string? SubType { get; set; } = "";
public string? Type { get; set; } = "";
public string? Units { get; set; } = "";
}
}
@@ -0,0 +1,48 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using MP.Data.Repository.Mtc;
using MP.Data.Repository.Utils;
using MP.Data.Services.Mtc;
using MP.Data.Services.Utils;
namespace MP.Data
{
public static class DataServiceCollectionExtensions
{
public static IServiceCollection AddIocDataLayer(this IServiceCollection services)
{
//// DbContextFactory: preferibile in Blazor Server e scenari concorrenti
//services.AddDbContextFactory<DataLayerContext>(options =>
// options.UseMySql(connectionString, ServerVersion.AutoDetect(connectionString)));
//// servizi preliminari
////services.TryAddSingleton<IConnectionMultiplexer>(redisConn);
//services.TryAddSingleton<IRedisService, RedisService>();
//services.TryAddSingleton<IRedisSubscriptionManager, RedisSubscriptionManager>();
// Repository Singleton
services.TryAddSingleton<IMtcSetupRepository, MtcSetupRepository>();
// Repository Scoped
services.TryAddScoped<IStatsAggrRepository, StatsAggrRepository>();
services.TryAddScoped<IStatsDetailRepository, StatsDetailRepository>();
// Servizi Singleton
services.TryAddSingleton<IMtcSetupService, MtcSetupService>();
// Servizi Scoped
services.TryAddScoped<IStatsAggrService, StatsAggrService>();
services.TryAddScoped<IStatsDetailService, StatsDetailService>();
//// aggiunta servizi finali Singleton...
//services.TryAddSingleton<IImageCacheService, ImageCacheService>();
//services.TryAddSingleton<IConfigDataService, ConfigDataService>();
//services.TryAddSingleton<ICalcRequestService, CalcRequestService>();
//services.TryAddSingleton<IFileService, FileService>();
//services.TryAddSingleton<IProdService, ProdService>();
return services;
}
}
}
+24
View File
@@ -0,0 +1,24 @@
using MP.Core.Objects;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Text.Json;
namespace MP.Data.DbModels.Mtc
{
[Table("mtc_setup")]
public class MtcSetupModel
{
[Key]
public string IdxMacchina { get; set; }
public string MtcDataItemsRaw { get; set; } = "";
[NotMapped]
public List<MachDataItem> MtcDataItems
{
get => string.IsNullOrWhiteSpace(MtcDataItemsRaw) ? new List<MachDataItem>() : JsonSerializer.Deserialize<List<MachDataItem>>(MtcDataItemsRaw) ?? new();
set => MtcDataItemsRaw = JsonSerializer.Serialize(value);
}
}
}
@@ -0,0 +1,127 @@
// <auto-generated />
using System;
using MP.Data;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
#nullable disable
namespace MP.Data.Migrations.MoonPro_Utils
{
[DbContext(typeof(MoonPro_UtilsContext))]
[Migration("20260423153623_AddMtcSetupModel")]
partial class AddMtcSetupModel
{
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.UseCollation("SQL_Latin1_General_CP1_CI_AS")
.HasAnnotation("ProductVersion", "6.0.36")
.HasAnnotation("Relational:MaxIdentifierLength", 128);
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder, 1L, 1);
modelBuilder.Entity("MP.Data.DbModels.Mtc.MtcSetupModel", b =>
{
b.Property<string>("IdxMacchina")
.HasColumnType("nvarchar(450)");
b.Property<string>("MtcDataItemsRaw")
.HasColumnType("nvarchar(max)");
b.HasKey("IdxMacchina");
b.ToTable("mtc_setup");
});
modelBuilder.Entity("MP.Data.DbModels.Utils.StatsAggregatedModel", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"), 1L, 1);
b.Property<double>("AvgDuration")
.HasColumnType("float");
b.Property<string>("Destination")
.HasColumnType("nvarchar(450)");
b.Property<DateTime>("Hour")
.HasColumnType("datetime2");
b.Property<string>("MachineId")
.HasColumnType("nvarchar(450)");
b.Property<double>("MaxDuration")
.HasColumnType("float");
b.Property<double>("MinDuration")
.HasColumnType("float");
b.Property<long>("NoReply")
.HasColumnType("bigint");
b.Property<long>("RequestCount")
.HasColumnType("bigint");
b.HasKey("Id");
b.HasIndex("Destination", "MachineId", "Hour")
.IsUnique()
.HasDatabaseName("idx_statsaggr_env_mach_hour")
.HasFilter("[Destination] IS NOT NULL AND [MachineId] IS NOT NULL");
b.ToTable("stats_aggr");
});
modelBuilder.Entity("MP.Data.DbModels.Utils.StatsDetailModel", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"), 1L, 1);
b.Property<double>("AvgDuration")
.HasColumnType("float");
b.Property<string>("Destination")
.HasColumnType("nvarchar(450)");
b.Property<DateTime>("Hour")
.HasColumnType("datetime2");
b.Property<double>("MaxDuration")
.HasColumnType("float");
b.Property<double>("MinDuration")
.HasColumnType("float");
b.Property<long>("NoReply")
.HasColumnType("bigint");
b.Property<long>("RequestCount")
.HasColumnType("bigint");
b.Property<string>("Type")
.HasColumnType("nvarchar(450)");
b.HasKey("Id");
b.HasIndex("Destination", "Type", "Hour")
.IsUnique()
.HasDatabaseName("idx_statsdet_hour_env_type")
.HasFilter("[Destination] IS NOT NULL AND [Type] IS NOT NULL");
b.ToTable("stats_detail");
});
#pragma warning restore 612, 618
}
}
}
@@ -0,0 +1,30 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace MP.Data.Migrations.MoonPro_Utils
{
public partial class AddMtcSetupModel : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "mtc_setup",
columns: table => new
{
IdxMacchina = table.Column<string>(type: "nvarchar(450)", nullable: false),
MtcDataItemsRaw = table.Column<string>(type: "nvarchar(max)", nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_mtc_setup", x => x.IdxMacchina);
});
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "mtc_setup");
}
}
}
@@ -23,6 +23,19 @@ namespace MP.Data.Migrations.MoonPro_Utils
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder, 1L, 1);
modelBuilder.Entity("MP.Data.DbModels.Mtc.MtcSetupModel", b =>
{
b.Property<string>("IdxMacchina")
.HasColumnType("nvarchar(450)");
b.Property<string>("MtcDataItemsRaw")
.HasColumnType("nvarchar(max)");
b.HasKey("IdxMacchina");
b.ToTable("mtc_setup");
});
modelBuilder.Entity("MP.Data.DbModels.Utils.StatsAggregatedModel", b =>
{
b.Property<int>("Id")
+16 -17
View File
@@ -108,7 +108,6 @@ namespace MP.Data
public virtual DbSet<TksScoreModel> DbSetTksScore { get; set; }
public virtual DbSet<RemoteRebootLogModel> DbSetRemRebLog { get; set; }
#endregion Public Properties
#region Private Methods
@@ -151,27 +150,27 @@ namespace MP.Data
modelBuilder.HasAnnotation("Relational:Collation", "SQL_Latin1_General_CP1_CI_AS");
modelBuilder.Entity<StatsAnagArticoli>(entity =>
{
entity.HasKey(e => e.CodArticolo);
{
entity.HasKey(e => e.CodArticolo);
entity.ToView("v_UI_AnagArticoli");
entity.ToView("v_UI_AnagArticoli");
entity.Property(e => e.CodArticolo)
.IsRequired()
.HasMaxLength(50);
entity.Property(e => e.CodArticolo)
.IsRequired()
.HasMaxLength(50);
entity.Property(e => e.DescArticolo)
.IsRequired()
.HasMaxLength(250);
entity.Property(e => e.DescArticolo)
.IsRequired()
.HasMaxLength(250);
entity.Property(e => e.Disegno)
.IsRequired()
.HasMaxLength(50);
entity.Property(e => e.Disegno)
.IsRequired()
.HasMaxLength(50);
entity.Property(e => e.Tipo)
.IsRequired()
.HasMaxLength(50);
});
entity.Property(e => e.Tipo)
.IsRequired()
.HasMaxLength(50);
});
modelBuilder.Entity<AnagArticoliModel>(entity =>
{
entity.HasKey(e => e.CodArticolo);
+2
View File
@@ -1,5 +1,6 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using MP.Data.DbModels.Mtc;
using MP.Data.DbModels.Utils;
using NLog;
using System;
@@ -47,6 +48,7 @@ namespace MP.Data
public virtual DbSet<StatsDetailModel> DbSetStatsDet { get; set; }
public virtual DbSet<StatsAggregatedModel> DbSetStatsAggr { get; set; }
public virtual DbSet<MtcSetupModel> DbSetMtcSetup { get; set; }
#endregion Public Properties
@@ -0,0 +1,36 @@
using MP.Data.DbModels.Mtc;
using System.Threading.Tasks;
namespace MP.Data.Repository.Mtc
{
public interface IMtcSetupRepository
{
/// <summary>
/// Recupero record richiesto
/// </summary>
/// <param name="idxMacchina"></param>
/// <returns></returns>
Task<MtcSetupModel> GetByIdxAsync(string idxMacchina);
/// <summary>
/// Inserimento nuovo record
/// </summary>
/// <param name="newRec"></param>
/// <returns></returns>
Task<bool> InsertAsync(MtcSetupModel newRec);
/// <summary>
/// Eliminazione record esistente
/// </summary>
/// <param name="idxMacchina"></param>
/// <returns></returns>
Task<bool> DeleteAsync(string idxMacchina);
/// <summary>
/// Update record esistente
/// </summary>
/// <param name="updRec"></param>
/// <returns></returns>
Task<bool> UpdateAsync(MtcSetupModel updRec);
}
}
@@ -0,0 +1,64 @@
using Microsoft.EntityFrameworkCore;
using MP.Data.DbModels.Mtc;
using System.Threading.Tasks;
namespace MP.Data.Repository.Mtc
{
public class MtcSetupRepository : BaseRepository, IMtcSetupRepository
{
#region Public Constructors
public MtcSetupRepository(IDbContextFactory<MoonPro_UtilsContext> ctxFactory) : base(ctxFactory)
{
}
#endregion Public Constructors
#region Public Methods
/// <inheritdoc />
public async Task<bool> DeleteAsync(string idxMacchina)
{
bool actRes = false;
await using var dbCtx = await CreateContextAsync();
var existing = await GetByIdxAsync(idxMacchina);
if (existing != null)
{
dbCtx.DbSetMtcSetup.Remove(existing);
actRes = await dbCtx.SaveChangesAsync() > 0;
}
return actRes;
}
/// <inheritdoc />
public async Task<MtcSetupModel> GetByIdxAsync(string idxMacchina)
{
await using var dbCtx = await CreateContextAsync();
return await dbCtx.DbSetMtcSetup
//.Include(s => s.MtcDataItems)
.FirstOrDefaultAsync(s => s.IdxMacchina == idxMacchina);
}
/// <inheritdoc />
public async Task<bool> InsertAsync(MtcSetupModel newRec)
{
bool actRes = false;
await using var dbCtx = await CreateContextAsync();
dbCtx.DbSetMtcSetup.Add(newRec);
actRes = await dbCtx.SaveChangesAsync() > 0;
return actRes;
}
/// <inheritdoc />
public async Task<bool> UpdateAsync(MtcSetupModel updRec)
{
bool actRes = false;
await using var dbCtx = await CreateContextAsync();
dbCtx.DbSetMtcSetup.Update(updRec);
actRes = await dbCtx.SaveChangesAsync() > 0;
return actRes;
}
#endregion Public Methods
}
}
+23
View File
@@ -0,0 +1,23 @@
using MP.Core.Objects;
using MP.Data.DbModels.Mtc;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace MP.Data.Services.Mtc
{
public interface IMtcSetupService
{
/// <summary>
/// Replace the data set for the specified machine.
/// Deletes existing record then inserts new one.
/// </summary>
Task<bool> ReplaceMachineDataAsync(string idxMacchina, List<MachDataItem> items);
/// <summary>
/// Retrieve all data for a given machine.
/// </summary>
Task<MtcSetupModel> GetMachineDataAsync(string idxMacchina);
}
}
+75
View File
@@ -0,0 +1,75 @@
using Microsoft.Extensions.Configuration;
using MP.Core.Objects;
using MP.Data.DbModels.Mtc;
using MP.Data.Repository.Mtc;
using StackExchange.Redis;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace MP.Data.Services.Mtc
{
// A lightweight service that mirrors the old Mongo based archive
public class MtcSetupService : BaseServ, IMtcSetupService
{
private readonly string _className;
private readonly IMtcSetupRepository _repo;
public MtcSetupService(
IConfiguration config,
IConnectionMultiplexer redis,
IMtcSetupRepository repo) : base(config, redis)
{
_className = "MtcSetup";
_repo = repo;
}
/// <inheritdoc />
public async Task<bool> ReplaceMachineDataAsync(string idxMacchina, List<MachDataItem> items)
{
return await TraceAsync($"{_className}.ReplaceMachineData", async (activity) =>
{
// cerso sul DB
var currRec = await _repo.GetByIdxAsync(idxMacchina);
var upsRec = new MtcSetupModel
{
IdxMacchina = idxMacchina,
MtcDataItems = items
};
string operation = "UPDATE";
bool success = false;
if (currRec != null)
{
success = await _repo.UpdateAsync(upsRec);
}
else
{
operation = "INSERT";
success = await _repo.InsertAsync(upsRec);
}
activity?.SetTag("db.operation", operation);
await ClearCacheAsync($"{_redisBaseKey}:{_className}:*");
return success;
});
}
/// <inheritdoc />
public async Task<MtcSetupModel> GetMachineDataAsync(string idxMacchina)
{
return await TraceAsync($"{_className}.GetMachineData", async (activity) =>
{
string cacheKey = $"{_redisBaseKey}:{_className}:MachData:{idxMacchina}";
return await GetOrSetCacheAsync(
cacheKey,
async () => await _repo.GetByIdxAsync(idxMacchina),
LongCache
);
});
}
}
}
+3 -1
View File
@@ -43,7 +43,9 @@ namespace MP.IOC.Components.Pages
DateTime oggi = DateTime.Today;
DateTime adesso = DateTime.Now;
var paretoDayCall = await StatsAggrService.GetParetoStatsDayAsync(0);
ListGlobalCall = paretoDayCall["Mach.Duration (ms)"];
ListGlobalCall.Clear();
var rawMachPareto = paretoDayCall["Mach.Duration (ms)"];
ListGlobalCall = rawMachPareto.Take(10).ToList();
ListParetoCall = await StatsDetService.GetParetoAsync(adesso.AddHours(-1), adesso, 10);
paretoWeek = await StatsAggrService.GetParetoStatsWeekAsync();
}
+29
View File
@@ -1003,6 +1003,35 @@ namespace MP.IOC.Controllers
return Ok(answ);
}
/// <summary>
/// Processa una chiamata POST per l'invio di un array Json di oggetti di conf DataItems (es
/// per MTC)
/// PUT: IOB/saveDataItems/SIMUL_03
/// </summary>
/// <param name="id">ID dell'IOB</param>
/// <returns></returns>
[HttpPost("saveDataItems/{id}")]
public async Task<IActionResult> SaveDataItems(string id, [FromBody] List<MachDataItem> dataList)
{
if (string.IsNullOrEmpty(id)) return BadRequest("Missing ID");
// Multi: gestione carattere "|" trasformato in "#"
id = id.Replace("|", "#");
string answ = "";
try
{
bool done = await DService.SaveDataItemsAsync(id, dataList);
answ = done ? "OK" : "KO";
}
catch (Exception exc)
{
Log.Error($"Errore in SaveDataItems{Environment.NewLine}{exc}");
return StatusCode(StatusCodes.Status500InternalServerError, "NO");
}
return Ok(answ);
}
/// <summary>
/// Processa una chiamata POST per l'invio di una Dictionary HashList da salvare in redis
/// POST: IOB/saveMachineIobConf/SIMUL_03
+90 -46
View File
@@ -3,9 +3,12 @@ using MP.Core.Conf;
using MP.Core.DTO;
using MP.Core.Objects;
using MP.Data;
using MP.Data.Controllers;
using MP.Data.DbModels;
using MP.Data.DbModels.Anag;
using MP.Data.MgModels;
using MP.Data.Repository.Mtc;
using MP.Data.Services.Mtc;
using Newtonsoft.Json;
using NLog;
using StackExchange.Redis;
@@ -20,11 +23,17 @@ namespace MP.IOC.Data
{
#region Public Constructors
public MpDataService(IConfiguration configuration, ILogger<MpDataService> logger)
public MpDataService(
IConfiguration configuration,
ILogger<MpDataService> logger,
IServiceScopeFactory scopeFactory,
IMtcSetupRepository mtcRepo,
IMtcSetupService mtcServ)
{
_logger = logger;
_logger.LogInformation("Starting MpDataService INIT");
_configuration = configuration;
_scopeFactory = scopeFactory;
// setup compoenti REDIS
redisConn = ConnectionMultiplexer.Connect(_configuration.GetConnectionString("Redis"));
@@ -35,6 +44,8 @@ namespace MP.IOC.Data
int.TryParse(_configuration.GetValue<string>("ServerConf:redisLongTimeCache"), out redisLongTimeCache);
int.TryParse(_configuration.GetValue<string>("ServerConf:redisShortTimeCache"), out redisShortTimeCache);
// gestione scope factory
useFactory = _configuration.GetValue<bool>("ServerConf:useFactory");
// conf base x servizi condivisi IO/IOC
MpIoNS = _configuration.GetValue<string>("ServerConf:MpIoNS") ?? "MP";
@@ -53,6 +64,9 @@ namespace MP.IOC.Data
_logger.LogInformation("DbControllers INIT OK");
}
MtcRepo = mtcRepo;
MtcService = mtcServ;
// conf mongo...
connStr = _configuration.GetConnectionString("mdbConnString");
if (string.IsNullOrEmpty(connStr))
@@ -73,6 +87,8 @@ namespace MP.IOC.Data
public static MP.Data.Controllers.MpIocController IocDbController { get; set; } = null!;
public static MP.Data.Controllers.MpMongoController mongoController { get; set; } = null!;
public static MP.Data.Controllers.MpSpecController SpecDbController { get; set; } = null!;
private static MP.Data.Services.Mtc.IMtcSetupService MtcService = null!;
private static MP.Data.Repository.Mtc.IMtcSetupRepository MtcRepo;
public MessagePipe BroadastMsgPipe { get; set; } = null!;
/// <summary>
@@ -1883,7 +1899,7 @@ namespace MP.IOC.Data
TimeSpan ts = stopWatch.Elapsed;
Log.Debug($"Macchine2SlaveGetAll | Read from {readType}: {ts.TotalMilliseconds}ms");
return result;
}
}
#endif
/// <summary>
@@ -1914,45 +1930,6 @@ namespace MP.IOC.Data
return result;
}
private async Task<HashSet<string>> ListMasterAsync()
{
HashSet<string> result = new();
string currKey = $"{Utils.redisBaseAddr}:ListMaster";
RedisValue rawData = await redisDb.StringGetAsync(currKey);
if (rawData.HasValue)
{
result = JsonConvert.DeserializeObject<HashSet<string>>($"{rawData}") ?? new();
}
else
{
var fullList = await Macchine2SlaveGetAllAsync();
result = fullList.Select(x => x.IdxMacchina).ToHashSet<string>();
// serializzo e salvo...
rawData = JsonConvert.SerializeObject(result);
await redisDb.StringSetAsync(currKey, rawData, getRandTOut(redisLongTimeCache * 10));
}
return result;
}
private async Task<HashSet<string>> ListSlaveAsync()
{
HashSet<string> result = new();
string currKey = $"{Utils.redisBaseAddr}:ListSlave";
RedisValue rawData = await redisDb.StringGetAsync(currKey);
if (rawData.HasValue)
{
result = JsonConvert.DeserializeObject<HashSet<string>>($"{rawData}") ?? new();
}
else
{
var fullList = await Macchine2SlaveGetAllAsync();
result = fullList.Select(x => x.IdxMacchinaSlave).Distinct().ToHashSet<string>();
// serializzo e salvo...
rawData = JsonConvert.SerializeObject(result);
await redisDb.StringSetAsync(currKey, rawData, getRandTOut(redisLongTimeCache * 10));
}
return result;
}
/// <summary>
/// Elenco di tutte le macchine gestite
/// </summary>
@@ -2235,7 +2212,6 @@ namespace MP.IOC.Data
return answ;
}
/// <summary>
/// Restitusice elenco KVP dei campi DatiMacchine + StatoMacchine per l'impianto indicato
/// </summary>
@@ -3788,6 +3764,24 @@ namespace MP.IOC.Data
return answ;
}
public async Task<bool> SaveDataItemsAsync(string id, List<MachDataItem> dataList)
{
bool answ = false;
if (useFactory)
{
await using var scope = _scopeFactory.CreateAsyncScope();
var mtcService = scope.ServiceProvider.GetRequiredService<IMtcSetupService>();
answ = await mtcService.ReplaceMachineDataAsync(id, dataList);
}
else
{
answ = await MtcService.ReplaceMachineDataAsync(id, dataList);
}
return answ;
}
public async Task<bool> SaveMachine2Iob(string idxMacchina, string serData)
{
bool fatto = false;
@@ -4164,10 +4158,9 @@ namespace MP.IOC.Data
#region Private Fields
private static IConfiguration _configuration = null!;
private static ILogger<MpDataService> _logger = null!;
private static Logger Log = LogManager.GetCurrentClassLogger();
private readonly IServiceScopeFactory _scopeFactory;
/// <summary>
/// MS max age x dato MSE
@@ -4200,6 +4193,8 @@ namespace MP.IOC.Data
private int redisShortTimeCache = 2;
private bool useFactory = false;
/// <summary>
/// Generatore random classe
/// </summary>
@@ -4419,6 +4414,46 @@ namespace MP.IOC.Data
return answ;
}
private async Task<HashSet<string>> ListMasterAsync()
{
HashSet<string> result = new();
string currKey = $"{Utils.redisBaseAddr}:ListMaster";
RedisValue rawData = await redisDb.StringGetAsync(currKey);
if (rawData.HasValue)
{
result = JsonConvert.DeserializeObject<HashSet<string>>($"{rawData}") ?? new();
}
else
{
var fullList = await Macchine2SlaveGetAllAsync();
result = fullList.Select(x => x.IdxMacchina).ToHashSet<string>();
// serializzo e salvo...
rawData = JsonConvert.SerializeObject(result);
await redisDb.StringSetAsync(currKey, rawData, getRandTOut(redisLongTimeCache * 10));
}
return result;
}
private async Task<HashSet<string>> ListSlaveAsync()
{
HashSet<string> result = new();
string currKey = $"{Utils.redisBaseAddr}:ListSlave";
RedisValue rawData = await redisDb.StringGetAsync(currKey);
if (rawData.HasValue)
{
result = JsonConvert.DeserializeObject<HashSet<string>>($"{rawData}") ?? new();
}
else
{
var fullList = await Macchine2SlaveGetAllAsync();
result = fullList.Select(x => x.IdxMacchinaSlave).Distinct().ToHashSet<string>();
// serializzo e salvo...
rawData = JsonConvert.SerializeObject(result);
await redisDb.StringSetAsync(currKey, rawData, getRandTOut(redisLongTimeCache * 10));
}
return result;
}
private async Task<bool> POdlFlushCache()
{
bool answ = false;
@@ -4499,8 +4534,17 @@ namespace MP.IOC.Data
private async Task<Dictionary<string, string>> ResetDatiMacchinaAsync(string idxMacc)
{
Dictionary<string, string> result = new Dictionary<string, string>();
var dbResult = await IocDbController.VMSFDGetByMaccAsync(idxMacc);
VMSFDModel? dbResult = null;
if (useFactory)
{
await using var scope = _scopeFactory.CreateAsyncScope();
var mtcService = scope.ServiceProvider.GetRequiredService<MpIocController>();
dbResult = await mtcService.VMSFDGetByMaccAsync(idxMacc);
}
else
{
dbResult = await IocDbController.VMSFDGetByMaccAsync(idxMacc);
}
if (dbResult == null) return new Dictionary<string, string>();
+1 -1
View File
@@ -4,7 +4,7 @@
<TargetFramework>net8.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<Version>6.16.2604.2308</Version>
<Version>6.16.2604.2407</Version>
</PropertyGroup>
<ItemGroup>
+3 -8
View File
@@ -3,8 +3,6 @@ using Microsoft.EntityFrameworkCore;
using Microsoft.OpenApi.Models;
using MP.Core.Conf;
using MP.Data;
using MP.Data.Repository.Utils;
using MP.Data.Services.Utils;
using MP.IOC.Components;
using MP.IOC.Data;
using MP.IOC.Services;
@@ -64,6 +62,9 @@ builder.Services.Configure<RedisScriptsConfig>(
builder.Configuration.GetSection("RedisScripts"));
logger.Info("RedisScript Provider configured");
// MP.Data Services Utils - Statistiche DB
builder.Services.AddIocDataLayer();
// base services
builder.Services.AddSingleton<PreserveBodyTransformer>();
builder.Services.AddSingleton<RouteStatsManager>();
@@ -83,12 +84,6 @@ string utilsConnString = builder.Configuration.GetConnectionString("MP.Utils") ?
builder.Services.AddDbContextFactory<MoonPro_UtilsContext>(options =>
options.UseSqlServer(utilsConnString));
// MP.Data Services Utils - Statistiche DB
builder.Services.AddScoped<IStatsAggrRepository, StatsAggrRepository>();
builder.Services.AddScoped<IStatsDetailRepository, StatsDetailRepository>();
builder.Services.AddScoped<IStatsAggrService, StatsAggrService>();
builder.Services.AddScoped<IStatsDetailService, StatsDetailService>();
// generic controller
builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
+1 -1
View File
@@ -1,6 +1,6 @@
<body>
<i>Modulo MP-IOC </i>
<h4>Versione: 6.16.2604.2308</h4>
<h4>Versione: 6.16.2604.2407</h4>
<br /> Note di rilascio:
<ul>
<li>
+1 -1
View File
@@ -1 +1 @@
6.16.2604.2308
6.16.2604.2407
+1 -1
View File
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<item>
<version>6.16.2604.2308</version>
<version>6.16.2604.2407</version>
<url>https://nexus.steamware.net/repository/SWS/MP-IOC/stable/LAST/MP.IOC.zip</url>
<changelog>https://nexus.steamware.net/repository/SWS/MP-IOC/stable/LAST/ChangeLog.html</changelog>
<mandatory>false</mandatory>
+2 -1
View File
@@ -86,7 +86,8 @@
"RoutePath": "/api/RIOB",
"SafePages": "Index",
"redisLongTimeCache": 60,
"redisShortTimeCache": 30
"redisShortTimeCache": 30,
"useFactory": true
},
"RedisScripts": {
"Scripts": {