using AsbCloudApp.Comparators; using AsbCloudApp.Data.SAUB; using AsbCloudApp.Services; using AsbCloudDb; using AsbCloudDb.Model; using Mapster; using Microsoft.Extensions.Caching.Memory; using System; using System.Collections.Generic; using System.Linq; using System.Threading; using System.Threading.Tasks; namespace AsbCloudInfrastructure.Services.SAUB { #nullable enable public class TelemetryUserService : ITelemetryUserService { private const string CacheTag = "TelemetryUserCacheTag"; private readonly TimeSpan CacheOlescence = TimeSpan.FromMinutes(5); private readonly IAsbCloudDbContext db; private readonly ITelemetryService telemetryService; private readonly IMemoryCache memoryCache; public TelemetryUserService(IAsbCloudDbContext db, ITelemetryService telemetryService, IMemoryCache memoryCache) { this.db = db; this.telemetryService = telemetryService; this.memoryCache = memoryCache; } public TelemetryUserDto? GetOrDefault(int idTelemetry, int idUser) { var entity = GetCache() .FirstOrDefault(u => u.IdTelemetry == idTelemetry && u.IdUser == idUser); if(entity is null) return null; return Convert(entity); } public IEnumerable GetUsers(int idTelemetry, Func? predicate = null) { var entities = GetCache() .Where(u => u.IdTelemetry == idTelemetry); foreach (var entity in entities) { var dto = Convert(entity); if(predicate?.Invoke(dto)??true) yield return dto; } yield break; } public async Task UpsertAsync(string uid, IEnumerable dtos, CancellationToken token = default) { if (!dtos.Any()) return; var telemetryId = telemetryService.GetOrCreateTelemetryIdByUid(uid); var entities = dtos.Distinct(new TelemetryUserDtoComparer()).Select(dto => { var entity = dto.Adapt(); entity.IdUser = dto.Id; entity.IdTelemetry = telemetryId; return entity; }); var result = await db.Database.ExecInsertOrUpdateAsync(db.TelemetryUsers, entities, token); DropCache(); } private IEnumerable GetCache() { var cache = memoryCache.GetOrCreate(CacheTag, cacheEntry => { cacheEntry.AbsoluteExpirationRelativeToNow = CacheOlescence; cacheEntry.SlidingExpiration = CacheOlescence; var entities = db.Set().ToArray(); return entities; }); return cache; } private void DropCache() => memoryCache.Remove(CacheTag); private static TelemetryUserDto Convert(TelemetryUser entity) { var dto = entity.Adapt(); dto.Id = entity.IdUser; return dto; } } #nullable disable }