diff --git a/AsbCloudApp/Data/SAUB/TelemetryUserDto.cs b/AsbCloudApp/Data/SAUB/TelemetryUserDto.cs index 5fb67dc0..ee2504e6 100644 --- a/AsbCloudApp/Data/SAUB/TelemetryUserDto.cs +++ b/AsbCloudApp/Data/SAUB/TelemetryUserDto.cs @@ -1,4 +1,6 @@ -namespace AsbCloudApp.Data.SAUB +using AsbCloudDb.Model; + +namespace AsbCloudApp.Data.SAUB { /// /// Пользователь панели оператора @@ -27,5 +29,26 @@ /// Уровень доступа /// public int Level { get; set; } + + /// + /// Собрать отображаемое имя пользователя + /// + /// + public string MakeDisplayName() + { + if (!string.IsNullOrEmpty(Surname)) + { + var s = Surname; + if (!string.IsNullOrEmpty(Name)) + { + s += $"{Name[0]}."; + if (!string.IsNullOrEmpty(Patronymic)) + s += $" {Patronymic[0]}."; + } + return s; + } + else + return $"User #{Id}"; + } } } diff --git a/AsbCloudApp/Services/ITelemetryUserService.cs b/AsbCloudApp/Services/ITelemetryUserService.cs index aa529634..558f24c5 100644 --- a/AsbCloudApp/Services/ITelemetryUserService.cs +++ b/AsbCloudApp/Services/ITelemetryUserService.cs @@ -1,15 +1,33 @@ using AsbCloudApp.Data.SAUB; +using System; using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; namespace AsbCloudApp.Services { +#nullable enable /// /// сервис пользователей телеметрии /// public interface ITelemetryUserService { + /// + /// get user by ids + /// + /// + /// + /// + TelemetryUserDto? GetOrDefault(int idTelemetry, int idUser); + + /// + /// get users by id telemetry and predicate + /// + /// + /// + /// + IEnumerable GetUsers(int idTelemetry, Func? predicate = default); + /// /// получает и сохраняет/обновляет список пользователей панели оператора /// @@ -19,4 +37,5 @@ namespace AsbCloudApp.Services /// Task UpsertAsync(string uid, IEnumerable dtos, CancellationToken token = default); } +#nullable disable } \ No newline at end of file diff --git a/AsbCloudInfrastructure/Services/SAUB/TelemetryDataBaseService.cs b/AsbCloudInfrastructure/Services/SAUB/TelemetryDataBaseService.cs index e918025a..6d67f9bc 100644 --- a/AsbCloudInfrastructure/Services/SAUB/TelemetryDataBaseService.cs +++ b/AsbCloudInfrastructure/Services/SAUB/TelemetryDataBaseService.cs @@ -19,18 +19,15 @@ namespace AsbCloudInfrastructure.Services.SAUB { protected readonly IAsbCloudDbContext db; private readonly ITelemetryService telemetryService; - protected readonly CacheTable cacheTelemetryUsers; private readonly TelemetryDataCache telemetryDataCache; public TelemetryDataBaseService( IAsbCloudDbContext db, ITelemetryService telemetryService, - TelemetryDataCache telemetryDataCache, - CacheDb cacheDb) + TelemetryDataCache telemetryDataCache) { this.db = db; this.telemetryService = telemetryService; - cacheTelemetryUsers = cacheDb.GetCachedTable((AsbCloudDbContext)db); this.telemetryDataCache = telemetryDataCache; } diff --git a/AsbCloudInfrastructure/Services/SAUB/TelemetryDataSaubService.cs b/AsbCloudInfrastructure/Services/SAUB/TelemetryDataSaubService.cs index 10a13913..aa6067b3 100644 --- a/AsbCloudInfrastructure/Services/SAUB/TelemetryDataSaubService.cs +++ b/AsbCloudInfrastructure/Services/SAUB/TelemetryDataSaubService.cs @@ -1,32 +1,33 @@ using AsbCloudApp.Data.SAUB; using AsbCloudApp.Services; using AsbCloudDb.Model; -using AsbCloudInfrastructure.Services.Cache; -using DocumentFormat.OpenXml.Drawing.Charts; using Mapster; -using Microsoft.EntityFrameworkCore; using System.Linq; -using System.Threading; -using System.Threading.Tasks; namespace AsbCloudInfrastructure.Services.SAUB { +#nullable enable public class TelemetryDataSaubService : TelemetryDataBaseService { + private readonly ITelemetryUserService telemetryUserService; + public TelemetryDataSaubService( IAsbCloudDbContext db, ITelemetryService telemetryService, - TelemetryDataCache telemetryDataCache, - CacheDb cacheDb) - : base(db, telemetryService, telemetryDataCache, cacheDb) - { } + ITelemetryUserService telemetryUserService, + TelemetryDataCache telemetryDataCache) + : base(db, telemetryService, telemetryDataCache) + { + this.telemetryUserService = telemetryUserService; + } public override TelemetryDataSaub Convert(TelemetryDataSaubDto src, double timezoneOffset) { var entity = src.Adapt(); - var telemetryUser = cacheTelemetryUsers? - .FirstOrDefault(u => u.IdTelemetry == src.IdTelemetry && (u.Name == src.User || u.Surname == src.User)); - entity.IdUser = telemetryUser?.IdUser; + var telemetryUser = telemetryUserService + .GetUsers(src.IdTelemetry, u => (u.Name == src.User || u.Surname == src.User)) + .FirstOrDefault(); + entity.IdUser = telemetryUser?.Id; entity.DateTime = src.DateTime.ToUtcDateTimeOffset(timezoneOffset); return entity; } @@ -34,11 +35,11 @@ namespace AsbCloudInfrastructure.Services.SAUB public override TelemetryDataSaubDto Convert(TelemetryDataSaub src, double timezoneOffset) { var dto = src.Adapt(); - var telemetryUser = cacheTelemetryUsers? - .FirstOrDefault(u => u.IdTelemetry == src.IdTelemetry && u.IdUser == src.IdUser); + var telemetryUser = telemetryUserService.GetOrDefault(src.IdTelemetry, src.IdUser??int.MinValue); dto.User = telemetryUser?.MakeDisplayName(); dto.DateTime = src.DateTime.ToRemoteDateTime(timezoneOffset); return dto; } } +#nullable disable } diff --git a/AsbCloudInfrastructure/Services/SAUB/TelemetryDataSpinService.cs b/AsbCloudInfrastructure/Services/SAUB/TelemetryDataSpinService.cs index 14e84955..64862dcc 100644 --- a/AsbCloudInfrastructure/Services/SAUB/TelemetryDataSpinService.cs +++ b/AsbCloudInfrastructure/Services/SAUB/TelemetryDataSpinService.cs @@ -1,10 +1,7 @@ using AsbCloudApp.Data.SAUB; using AsbCloudApp.Services; using AsbCloudDb.Model; -using AsbCloudInfrastructure.Services.Cache; using Mapster; -using System.Threading; -using System.Threading.Tasks; namespace AsbCloudInfrastructure.Services.SAUB { @@ -13,9 +10,8 @@ namespace AsbCloudInfrastructure.Services.SAUB public TelemetryDataSpinService( IAsbCloudDbContext db, ITelemetryService telemetryService, - TelemetryDataCache telemetryDataCache, - CacheDb cacheDb) - : base(db, telemetryService, telemetryDataCache, cacheDb) + TelemetryDataCache telemetryDataCache) + : base(db, telemetryService, telemetryDataCache) { } public override TelemetryDataSpin Convert(TelemetryDataSpinDto src, double timezoneOffset) diff --git a/AsbCloudInfrastructure/Services/SAUB/TelemetryUserService.cs b/AsbCloudInfrastructure/Services/SAUB/TelemetryUserService.cs index 2406a2b0..f5740a3c 100644 --- a/AsbCloudInfrastructure/Services/SAUB/TelemetryUserService.cs +++ b/AsbCloudInfrastructure/Services/SAUB/TelemetryUserService.cs @@ -3,7 +3,9 @@ using AsbCloudApp.Data.SAUB; using AsbCloudApp.Services; using AsbCloudDb; using AsbCloudDb.Model; -using AsbCloudInfrastructure.EfCache; +using Mapster; +using Microsoft.Extensions.Caching.Memory; +using System; using System.Collections.Generic; using System.Linq; using System.Threading; @@ -11,15 +13,49 @@ 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) + 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) @@ -29,17 +65,37 @@ namespace AsbCloudInfrastructure.Services.SAUB var telemetryId = telemetryService.GetOrCreateTelemetryIdByUid(uid); - var entities = dtos.Distinct(new TelemetryUserDtoComparer()).Select(dto => new TelemetryUser - { - IdUser = dto.Id, - IdTelemetry = telemetryId, - Level = dto.Level, - Name = dto.Name, - Patronymic = dto.Patronymic, - Surname = dto.Surname, + 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); - db.TelemetryUsers.DropCache(); + 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 } diff --git a/AsbCloudWebApi/Controllers/SAUB/TelemetryController.cs b/AsbCloudWebApi/Controllers/SAUB/TelemetryController.cs index 4a77088a..f7fe0b74 100644 --- a/AsbCloudWebApi/Controllers/SAUB/TelemetryController.cs +++ b/AsbCloudWebApi/Controllers/SAUB/TelemetryController.cs @@ -1,5 +1,4 @@ -using AsbCloudApp.Data; -using AsbCloudApp.Data.SAUB; +using AsbCloudApp.Data.SAUB; using AsbCloudApp.Services; using AsbCloudWebApi.SignalR; using Microsoft.AspNetCore.Mvc;