TelemetryUserService добавлен microsoft cache

This commit is contained in:
ngfrolov 2022-11-18 12:58:53 +05:00
parent abb6a513fd
commit de6bbcfa72
7 changed files with 129 additions and 38 deletions

View File

@ -1,4 +1,6 @@
namespace AsbCloudApp.Data.SAUB
using AsbCloudDb.Model;
namespace AsbCloudApp.Data.SAUB
{
/// <summary>
/// Пользователь панели оператора
@ -27,5 +29,26 @@
/// Уровень доступа
/// </summary>
public int Level { get; set; }
/// <summary>
/// Собрать отображаемое имя пользователя
/// </summary>
/// <returns></returns>
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}";
}
}
}

View File

@ -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
/// <summary>
/// сервис пользователей телеметрии
/// </summary>
public interface ITelemetryUserService
{
/// <summary>
/// get user by ids
/// </summary>
/// <param name="idTelemetry"></param>
/// <param name="idUser"></param>
/// <returns></returns>
TelemetryUserDto? GetOrDefault(int idTelemetry, int idUser);
/// <summary>
/// get users by id telemetry and predicate
/// </summary>
/// <param name="idTelemetry"></param>
/// <param name="predicate"></param>
/// <returns></returns>
IEnumerable<TelemetryUserDto> GetUsers(int idTelemetry, Func<TelemetryUserDto, bool>? predicate = default);
/// <summary>
/// получает и сохраняет/обновляет список пользователей панели оператора
/// </summary>
@ -19,4 +37,5 @@ namespace AsbCloudApp.Services
/// <returns></returns>
Task UpsertAsync(string uid, IEnumerable<TelemetryUserDto> dtos, CancellationToken token = default);
}
#nullable disable
}

View File

@ -19,18 +19,15 @@ namespace AsbCloudInfrastructure.Services.SAUB
{
protected readonly IAsbCloudDbContext db;
private readonly ITelemetryService telemetryService;
protected readonly CacheTable<TelemetryUser> cacheTelemetryUsers;
private readonly TelemetryDataCache<TDto> telemetryDataCache;
public TelemetryDataBaseService(
IAsbCloudDbContext db,
ITelemetryService telemetryService,
TelemetryDataCache<TDto> telemetryDataCache,
CacheDb cacheDb)
TelemetryDataCache<TDto> telemetryDataCache)
{
this.db = db;
this.telemetryService = telemetryService;
cacheTelemetryUsers = cacheDb.GetCachedTable<TelemetryUser>((AsbCloudDbContext)db);
this.telemetryDataCache = telemetryDataCache;
}

View File

@ -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<TelemetryDataSaubDto, TelemetryDataSaub>
{
private readonly ITelemetryUserService telemetryUserService;
public TelemetryDataSaubService(
IAsbCloudDbContext db,
ITelemetryService telemetryService,
TelemetryDataCache<TelemetryDataSaubDto> telemetryDataCache,
CacheDb cacheDb)
: base(db, telemetryService, telemetryDataCache, cacheDb)
{ }
ITelemetryUserService telemetryUserService,
TelemetryDataCache<TelemetryDataSaubDto> telemetryDataCache)
: base(db, telemetryService, telemetryDataCache)
{
this.telemetryUserService = telemetryUserService;
}
public override TelemetryDataSaub Convert(TelemetryDataSaubDto src, double timezoneOffset)
{
var entity = src.Adapt<TelemetryDataSaub>();
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<TelemetryDataSaubDto>();
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
}

View File

@ -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<TelemetryDataSpinDto> telemetryDataCache,
CacheDb cacheDb)
: base(db, telemetryService, telemetryDataCache, cacheDb)
TelemetryDataCache<TelemetryDataSpinDto> telemetryDataCache)
: base(db, telemetryService, telemetryDataCache)
{ }
public override TelemetryDataSpin Convert(TelemetryDataSpinDto src, double timezoneOffset)

View File

@ -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<TelemetryUserDto> GetUsers(int idTelemetry, Func<TelemetryUserDto, bool>? 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<TelemetryUserDto> 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<TelemetryUser>();
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<TelemetryUser> GetCache()
{
var cache = memoryCache.GetOrCreate(CacheTag, cacheEntry => {
cacheEntry.AbsoluteExpirationRelativeToNow = CacheOlescence;
cacheEntry.SlidingExpiration = CacheOlescence;
var entities = db.Set<TelemetryUser>().ToArray();
return entities;
});
return cache;
}
private void DropCache()
=> memoryCache.Remove(CacheTag);
private static TelemetryUserDto Convert(TelemetryUser entity)
{
var dto = entity.Adapt<TelemetryUserDto>();
dto.Id = entity.IdUser;
return dto;
}
}
#nullable disable
}

View File

@ -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;