forked from ddrilling/AsbCloudServer
Кэш телеметрии
1. Небольшой рефакторинг 2. Покрытие кода тестами
This commit is contained in:
parent
a5c1722712
commit
86af253df7
@ -6,7 +6,6 @@ using System.Linq;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Mapster;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using AsbCloudInfrastructure.Background;
|
||||
using System.Threading;
|
||||
@ -25,7 +24,6 @@ namespace AsbCloudInfrastructure.Services.SAUB
|
||||
public double TimezoneHours { get; init; } = 5;
|
||||
}
|
||||
|
||||
private IServiceProvider provider = null!;
|
||||
private const int activeWellCapacity = 12 * 60 * 60;
|
||||
private const int doneWellCapacity = 65 * 60;
|
||||
|
||||
@ -40,6 +38,8 @@ namespace AsbCloudInfrastructure.Services.SAUB
|
||||
|
||||
private static TelemetryDataCache<TDto>? instance;
|
||||
|
||||
public int CacheItemCount => caches.Count;
|
||||
|
||||
public static TelemetryDataCache<TDto> GetInstance<TEntity>(IServiceProvider provider)
|
||||
where TEntity : class, AsbCloudDb.Model.ITelemetryData
|
||||
{
|
||||
@ -55,7 +55,6 @@ namespace AsbCloudInfrastructure.Services.SAUB
|
||||
work.Timeout = TimeSpan.FromMinutes(15);
|
||||
worker.WorkStore.RunOnceQueue.Enqueue(work);
|
||||
}
|
||||
instance.provider = provider;
|
||||
return instance;
|
||||
}
|
||||
|
||||
@ -69,10 +68,9 @@ namespace AsbCloudInfrastructure.Services.SAUB
|
||||
if (!range.Any())
|
||||
return;
|
||||
|
||||
var newItems = range
|
||||
.OrderBy(i => i.DateTime);
|
||||
range = range.OrderBy(x => x.DateTime);
|
||||
|
||||
foreach (var item in newItems)
|
||||
foreach (var item in range)
|
||||
item.IdTelemetry = idTelemetry;
|
||||
|
||||
TelemetryDataCacheItem cacheItem;
|
||||
@ -87,12 +85,12 @@ namespace AsbCloudInfrastructure.Services.SAUB
|
||||
{
|
||||
cacheItem = caches.GetOrAdd(idTelemetry, _ => new TelemetryDataCacheItem()
|
||||
{
|
||||
FirstByDate = newItems.ElementAt(0),
|
||||
FirstByDate = range.ElementAt(0),
|
||||
LastData = new CyclycArray<TDto>(activeWellCapacity)
|
||||
});
|
||||
}
|
||||
|
||||
cacheItem.LastData.AddRange(newItems);
|
||||
cacheItem.LastData.AddRange(range);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -152,13 +150,14 @@ namespace AsbCloudInfrastructure.Services.SAUB
|
||||
|
||||
private async Task InitializeCacheFromDBAsync<TEntity>(IAsbCloudDbContext db, Action<string, double?> onProgress, CancellationToken token)
|
||||
where TEntity : class, AsbCloudDb.Model.ITelemetryData
|
||||
{
|
||||
try
|
||||
{
|
||||
if (isLoading)
|
||||
throw new Exception("Multiple cache loading detected.");
|
||||
|
||||
isLoading = true;
|
||||
|
||||
var defaultTimeout = db.Database.GetCommandTimeout();
|
||||
db.Database.SetCommandTimeout(TimeSpan.FromMinutes(5));
|
||||
|
||||
Well[] wells = await db.Set<Well>()
|
||||
@ -183,10 +182,14 @@ namespace AsbCloudInfrastructure.Services.SAUB
|
||||
if(cacheItem is not null)
|
||||
caches.TryAdd(idTelemetry, cacheItem);
|
||||
}
|
||||
|
||||
}
|
||||
finally
|
||||
{
|
||||
isLoading = false;
|
||||
var defaultTimeout = db.Database.GetCommandTimeout();
|
||||
db.Database.SetCommandTimeout(defaultTimeout);
|
||||
}
|
||||
}
|
||||
|
||||
private static async Task<TelemetryDataCacheItem?> GetOrDefaultCacheDataFromDbAsync<TEntity>(IAsbCloudDbContext db, int idTelemetry, int capacity, double hoursOffset, CancellationToken token)
|
||||
where TEntity : class, AsbCloudDb.Model.ITelemetryData
|
||||
|
@ -9,6 +9,7 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Bogus" Version="34.0.2" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="6.0.8" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="6.0.8" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="6.0.8" />
|
||||
|
@ -0,0 +1,69 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using AsbCloudApp.Data.SAUB;
|
||||
using AsbCloudDb.Model;
|
||||
using AsbCloudInfrastructure.Background;
|
||||
using AsbCloudInfrastructure.Services.SAUB;
|
||||
using Bogus;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using NSubstitute;
|
||||
using Xunit;
|
||||
|
||||
namespace AsbCloudWebApi.Tests.ServicesTests.SAUB;
|
||||
|
||||
public class TelemetryDataSaubCacheTests
|
||||
{
|
||||
private readonly IEnumerable<TelemetryDataSaubDto> fakeTelemetries = new Faker<TelemetryDataSaubDto>()
|
||||
.RuleFor(t => t.DateTime, DateTime.UtcNow)
|
||||
.Generate(5)
|
||||
.OrderBy(t => t.DateTime);
|
||||
|
||||
private readonly IServiceProvider serviceProvider = Substitute.For<IServiceProvider>();
|
||||
|
||||
private readonly TelemetryDataCache<TelemetryDataSaubDto> telemetryDataCache;
|
||||
|
||||
public TelemetryDataSaubCacheTests()
|
||||
{
|
||||
serviceProvider.GetService<BackgroundWorker>().Returns(new BackgroundWorker(serviceProvider));
|
||||
|
||||
telemetryDataCache = TelemetryDataCache<TelemetryDataSaubDto>.GetInstance<TelemetryDataSaub>(serviceProvider);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void AddRange_ShouldReturn_OneAddedElementToCache()
|
||||
{
|
||||
//arrange
|
||||
const int expectedCacheItemCount = 1;
|
||||
|
||||
var idTelemetry = new Random().Next(1, 100);
|
||||
var telemetryDataCacheType = telemetryDataCache.GetType();
|
||||
|
||||
telemetryDataCacheType.GetField("isLoading", BindingFlags.NonPublic | BindingFlags.Instance)?.SetValue(telemetryDataCache, false);
|
||||
|
||||
//act
|
||||
telemetryDataCache.AddRange(idTelemetry, fakeTelemetries);
|
||||
|
||||
//assert
|
||||
Assert.True(telemetryDataCache.CacheItemCount == expectedCacheItemCount);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void AddRange_ShouldReturn_ZeroAddedElementToCache()
|
||||
{
|
||||
//arrange
|
||||
const int expectedCacheItemCount = 0;
|
||||
|
||||
var idTelemetry = new Random().Next(1, 100);
|
||||
var telemetryDataCacheType = telemetryDataCache.GetType();
|
||||
|
||||
telemetryDataCacheType.GetField("isLoading", BindingFlags.NonPublic | BindingFlags.Instance)?.SetValue(telemetryDataCache, true);
|
||||
|
||||
//act
|
||||
telemetryDataCache.AddRange(idTelemetry, fakeTelemetries);
|
||||
|
||||
//assert
|
||||
Assert.True(telemetryDataCache.CacheItemCount == expectedCacheItemCount);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user