DD.WellWorkover.Cloud/AsbCloudInfrastructure/Services/SAUB/TelemetryUserService.cs
2023-06-20 14:41:19 +05:00

102 lines
3.2 KiB
C#

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
{
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<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)
{
if (!dtos.Any())
return;
var telemetry = telemetryService.GetOrCreateTelemetryByUid(uid);
var entities = dtos.Distinct(new TelemetryUserDtoComparer()).Select(dto => {
var entity = dto.Adapt<TelemetryUser>();
entity.IdUser = dto.Id;
entity.IdTelemetry = telemetry.Id;
return entity;
});
var result = await db.Database.ExecInsertOrUpdateAsync(db.TelemetryUsers, entities, token);
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;
}
}
}