forked from ddrilling/AsbCloudServer
Merge branch 'fix/save-fact-operations' of http://test.digitaldrilling.ru:8080/DDrilling/AsbCloudServer into fix/save-fact-operations
This commit is contained in:
commit
1e54fb3b16
@ -16,11 +16,6 @@ namespace AsbCloudApp.Services
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
ITimezoneService TimeZoneService { get; }
|
ITimezoneService TimeZoneService { get; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// трекер запросов
|
|
||||||
/// </summary>
|
|
||||||
ITelemetryTracker TelemetryTracker { get; }
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// получить idWell по uid телеметрии
|
/// получить idWell по uid телеметрии
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -42,13 +37,6 @@ namespace AsbCloudApp.Services
|
|||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
SimpleTimezoneDto GetTimezone(int idTelemetry);
|
SimpleTimezoneDto GetTimezone(int idTelemetry);
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Получить дату получения последних данных
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="idTelemetry"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
DateTime GetLastTelemetryDate(int idTelemetry);
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// получить idTelemetry по IdWell
|
/// получить idTelemetry по IdWell
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -1,39 +0,0 @@
|
|||||||
using AsbCloudApp.Data;
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
|
|
||||||
namespace AsbCloudApp.Services
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Сервис статистики телеметрии
|
|
||||||
/// </summary>
|
|
||||||
public interface ITelemetryTracker
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// получить дату последней отправки данных панелью
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="uid"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
DateTimeOffset GetLastTelemetryDateByUid(string uid);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// получить диапазон дат за которые есть данные по телеметрии
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="uid"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
DatesRangeDto GetTelemetryDateRangeByUid(string uid);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// список передающих телеметрий
|
|
||||||
/// </summary>
|
|
||||||
/// <returns></returns>
|
|
||||||
IEnumerable<string> GetTransmittingTelemetriesUids();
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// обновить статистику по телеметрии
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="uid"></param>
|
|
||||||
/// <param name="remoteDate"></param>
|
|
||||||
void SaveRequestDate(string uid, DateTimeOffset remoteDate);
|
|
||||||
}
|
|
||||||
}
|
|
@ -63,7 +63,7 @@ namespace AsbCloudApp.Services
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="idWell"></param>
|
/// <param name="idWell"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
DateTimeOffset GetLastTelemetryDate(int idWell);
|
DateTime GetLastTelemetryDate(int idWell);
|
||||||
|
|
||||||
//TODO: выяснить и удалить отсюда
|
//TODO: выяснить и удалить отсюда
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -1,12 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Concurrent;
|
|
||||||
|
|
||||||
namespace AsbCloudApp.Services
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Репозиторий для хранения в оперативке данных (от панели)
|
|
||||||
/// </summary>
|
|
||||||
public class InstantDataRepository : ConcurrentDictionary<int, ConcurrentDictionary<Type, object>>
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,12 +1,10 @@
|
|||||||
using AsbCloudApp.Data;
|
using AsbCloudApp.Data;
|
||||||
using AsbCloudApp.Data.GTR;
|
|
||||||
using AsbCloudApp.Data.SAUB;
|
using AsbCloudApp.Data.SAUB;
|
||||||
using AsbCloudApp.Data.Subsystems;
|
using AsbCloudApp.Data.Subsystems;
|
||||||
using AsbCloudApp.Repositories;
|
using AsbCloudApp.Repositories;
|
||||||
using AsbCloudApp.Services;
|
using AsbCloudApp.Services;
|
||||||
using AsbCloudApp.Services.Subsystems;
|
using AsbCloudApp.Services.Subsystems;
|
||||||
using AsbCloudDb.Model;
|
using AsbCloudDb.Model;
|
||||||
using AsbCloudDb.Model.GTR;
|
|
||||||
using AsbCloudDb.Model.Subsystems;
|
using AsbCloudDb.Model.Subsystems;
|
||||||
using AsbCloudInfrastructure.Background;
|
using AsbCloudInfrastructure.Background;
|
||||||
using AsbCloudInfrastructure.Repository;
|
using AsbCloudInfrastructure.Repository;
|
||||||
@ -102,10 +100,8 @@ namespace AsbCloudInfrastructure
|
|||||||
services.AddScoped<IEmailService, EmailService>();
|
services.AddScoped<IEmailService, EmailService>();
|
||||||
|
|
||||||
services.AddSingleton(new WitsInfoService());
|
services.AddSingleton(new WitsInfoService());
|
||||||
services.AddSingleton(new InstantDataRepository());
|
services.AddSingleton(provider => TelemetryDataCache<TelemetryDataSaubDto>.GetInstance<TelemetryDataSaub>(provider));
|
||||||
services.AddSingleton(provider=> TelemetryDataCache<TelemetryDataSaubDto>.GetInstance<TelemetryDataSaub>(configuration));
|
services.AddSingleton(provider => TelemetryDataCache<TelemetryDataSpinDto>.GetInstance<TelemetryDataSpin>(provider));
|
||||||
services.AddSingleton(provider=> TelemetryDataCache<TelemetryDataSpinDto>.GetInstance<TelemetryDataSpin>(configuration));
|
|
||||||
services.AddSingleton<ITelemetryTracker, TelemetryTracker>();
|
|
||||||
services.AddSingleton<IRequerstTrackerService, RequestTrackerService>();
|
services.AddSingleton<IRequerstTrackerService, RequestTrackerService>();
|
||||||
services.AddSingleton<BackgroundWorker>();
|
services.AddSingleton<BackgroundWorker>();
|
||||||
services.AddSingleton<IReduceSamplingService>(provider => ReduceSamplingService.GetInstance(configuration));
|
services.AddSingleton<IReduceSamplingService>(provider => ReduceSamplingService.GetInstance(configuration));
|
||||||
|
@ -111,7 +111,7 @@ namespace AsbCloudInfrastructure.Repository
|
|||||||
{
|
{
|
||||||
var dto = well.Adapt<WellDto>();
|
var dto = well.Adapt<WellDto>();
|
||||||
dto.WellType = well.WellType.Caption;
|
dto.WellType = well.WellType.Caption;
|
||||||
dto.LastTelemetryDate = wellService.GetLastTelemetryDate(well.Id).DateTime;
|
dto.LastTelemetryDate = wellService.GetLastTelemetryDate(well.Id);
|
||||||
dto.Cluster = gCluster.Key.Caption;
|
dto.Cluster = gCluster.Key.Caption;
|
||||||
dto.Deposit = gDeposit.Key.Caption;
|
dto.Deposit = gDeposit.Key.Caption;
|
||||||
return dto;
|
return dto;
|
||||||
|
@ -64,7 +64,6 @@ namespace AsbCloudInfrastructure.Services.SAUB
|
|||||||
});
|
});
|
||||||
|
|
||||||
var entityMaxDate = entities.Max(e => e.DateTime);
|
var entityMaxDate = entities.Max(e => e.DateTime);
|
||||||
telemetryService.TelemetryTracker.SaveRequestDate(uid, entityMaxDate);
|
|
||||||
|
|
||||||
var dbset = db.Set<TEntity>();
|
var dbset = db.Set<TEntity>();
|
||||||
var stopwatch = Stopwatch.StartNew();
|
var stopwatch = Stopwatch.StartNew();
|
||||||
@ -101,19 +100,15 @@ namespace AsbCloudInfrastructure.Services.SAUB
|
|||||||
DateTimeOffset dateBeginUtc;
|
DateTimeOffset dateBeginUtc;
|
||||||
if (dateBegin == default)
|
if (dateBegin == default)
|
||||||
{
|
{
|
||||||
dateBeginUtc = telemetryService.GetLastTelemetryDate(telemetry.Id)
|
var dateRange = telemetryDataCache.GetOrDefaultDataDateRange(telemetry.Id);
|
||||||
.ToUtcDateTimeOffset(timezone.Hours);
|
dateBeginUtc = (dateRange?.To.ToUtcDateTimeOffset(timezone.Hours) ?? DateTime.UtcNow)
|
||||||
if (dateBeginUtc != default)
|
.AddSeconds(-intervalSec);
|
||||||
dateBeginUtc = dateBeginUtc.AddSeconds(-intervalSec);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
dateBeginUtc = dateBegin.ToUtcDateTimeOffset(timezone.Hours);
|
dateBeginUtc = dateBegin.ToUtcDateTimeOffset(timezone.Hours);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dateBeginUtc == default)
|
|
||||||
dateBeginUtc = DateTime.UtcNow.AddSeconds(-intervalSec);
|
|
||||||
|
|
||||||
var cacheData = telemetryDataCache.GetOrDefault(telemetry.Id, dateBeginUtc.ToRemoteDateTime(timezone.Hours), intervalSec, approxPointsCount);
|
var cacheData = telemetryDataCache.GetOrDefault(telemetry.Id, dateBeginUtc.ToRemoteDateTime(timezone.Hours), intervalSec, approxPointsCount);
|
||||||
if (cacheData is not null)
|
if (cacheData is not null)
|
||||||
return cacheData;
|
return cacheData;
|
||||||
|
@ -7,17 +7,28 @@ using Microsoft.EntityFrameworkCore;
|
|||||||
using Mapster;
|
using Mapster;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.Extensions.Configuration;
|
using Microsoft.Extensions.Configuration;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using AsbCloudInfrastructure.Background;
|
||||||
|
using System.Threading;
|
||||||
|
using AsbCloudApp.Data;
|
||||||
|
|
||||||
namespace AsbCloudInfrastructure.Services.SAUB
|
namespace AsbCloudInfrastructure.Services.SAUB
|
||||||
{
|
{
|
||||||
public class TelemetryDataCache<TDto>
|
public class TelemetryDataCache<TDto>
|
||||||
where TDto : AsbCloudApp.Data.ITelemetryData
|
where TDto : AsbCloudApp.Data.ITelemetryData
|
||||||
{
|
{
|
||||||
|
class TelemetryDataCacheItem
|
||||||
|
{
|
||||||
|
public TDto? FirstByDate { get; init; }
|
||||||
|
public CyclycArray<TDto> LastData { get; init; } = null!;
|
||||||
|
}
|
||||||
|
|
||||||
|
private IServiceProvider provider = null!;
|
||||||
private const int activeWellCapacity = 12 * 60 * 60;
|
private const int activeWellCapacity = 12 * 60 * 60;
|
||||||
private const int doneWellCapacity = 65 * 60;
|
private const int doneWellCapacity = 65 * 60;
|
||||||
|
|
||||||
private readonly ConcurrentDictionary<int, CyclycArray<TDto>> caches;
|
// key == idTelemetry
|
||||||
|
private readonly ConcurrentDictionary<int, TelemetryDataCacheItem> caches;
|
||||||
private bool isLoading = false;
|
private bool isLoading = false;
|
||||||
|
|
||||||
private TelemetryDataCache()
|
private TelemetryDataCache()
|
||||||
@ -27,35 +38,22 @@ namespace AsbCloudInfrastructure.Services.SAUB
|
|||||||
|
|
||||||
private static TelemetryDataCache<TDto>? instance;
|
private static TelemetryDataCache<TDto>? instance;
|
||||||
|
|
||||||
//TODO: Move initialize fromDB to bacground service task
|
public static TelemetryDataCache<TDto> GetInstance<TEntity>(IServiceProvider provider)
|
||||||
public static TelemetryDataCache<TDto> GetInstance<TEntity>(IConfiguration configuration)
|
where TEntity : class, AsbCloudDb.Model.ITelemetryData
|
||||||
where TEntity : class, ITelemetryData
|
|
||||||
{
|
{
|
||||||
if (instance is null)
|
if (instance is null)
|
||||||
{
|
{
|
||||||
instance = new TelemetryDataCache<TDto>();
|
instance = new TelemetryDataCache<TDto>();
|
||||||
_ = Task.Run(() =>
|
var worker = provider.GetRequiredService<BackgroundWorker>();
|
||||||
{
|
var workId = $"Telemetry cache loading from DB {typeof(TEntity).Name}";
|
||||||
using var db = MakeContext(configuration);
|
var work = new WorkBase(workId, async (workId, provider, token) => {
|
||||||
instance.InitializeCacheFromDB<TEntity>(db);
|
var db = provider.GetRequiredService<IAsbCloudDbContext>();
|
||||||
db.Dispose();
|
await instance.InitializeCacheFromDBAsync<TEntity>(db, token);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
worker.Push(work);
|
||||||
}
|
}
|
||||||
return instance;
|
instance.provider = provider;
|
||||||
}
|
|
||||||
public static TelemetryDataCache<TDto> GetInstance<TEntity>(IAsbCloudDbContext db, out Task initializationTask)
|
|
||||||
where TEntity : class, ITelemetryData
|
|
||||||
{
|
|
||||||
if (instance is null)
|
|
||||||
{
|
|
||||||
instance = new TelemetryDataCache<TDto>();
|
|
||||||
initializationTask = Task.Run(() =>
|
|
||||||
{
|
|
||||||
instance.InitializeCacheFromDB<TEntity>(db);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
else
|
|
||||||
initializationTask = Task.CompletedTask;
|
|
||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -66,24 +64,33 @@ namespace AsbCloudInfrastructure.Services.SAUB
|
|||||||
/// <param name="range"></param>
|
/// <param name="range"></param>
|
||||||
public void AddRange(int idTelemetry, IEnumerable<TDto> range)
|
public void AddRange(int idTelemetry, IEnumerable<TDto> range)
|
||||||
{
|
{
|
||||||
CyclycArray<TDto> cacheItem;
|
if (!range.Any())
|
||||||
|
return;
|
||||||
|
|
||||||
|
var newItems = range
|
||||||
|
.OrderBy(i => i.DateTime);
|
||||||
|
|
||||||
|
foreach (var item in newItems)
|
||||||
|
item.IdTelemetry = idTelemetry;
|
||||||
|
|
||||||
|
TelemetryDataCacheItem cacheItem;
|
||||||
if (isLoading)
|
if (isLoading)
|
||||||
{
|
{
|
||||||
if (caches.TryGetValue(idTelemetry, out CyclycArray<TDto>? localCacheItem))
|
if (caches.TryGetValue(idTelemetry, out TelemetryDataCacheItem? localCacheItem))
|
||||||
cacheItem = localCacheItem;
|
cacheItem = localCacheItem;
|
||||||
else
|
else
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
cacheItem = caches.GetOrAdd(idTelemetry, _ => new CyclycArray<TDto>(activeWellCapacity));
|
cacheItem = caches.GetOrAdd(idTelemetry, _ => new TelemetryDataCacheItem()
|
||||||
|
{
|
||||||
|
FirstByDate = newItems.ElementAt(0),
|
||||||
|
LastData = new CyclycArray<TDto>(activeWellCapacity)
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
var newItems = range
|
cacheItem.LastData.AddRange(newItems);
|
||||||
.OrderBy(i => i.DateTime);
|
|
||||||
foreach (var item in newItems)
|
|
||||||
item.IdTelemetry = idTelemetry;
|
|
||||||
cacheItem.AddRange(newItems);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -98,14 +105,16 @@ namespace AsbCloudInfrastructure.Services.SAUB
|
|||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public IEnumerable<TDto>? GetOrDefault(int idTelemetry, DateTime dateBegin, double intervalSec = 600d, int approxPointsCount = 1024)
|
public IEnumerable<TDto>? GetOrDefault(int idTelemetry, DateTime dateBegin, double intervalSec = 600d, int approxPointsCount = 1024)
|
||||||
{
|
{
|
||||||
if(!caches.TryGetValue(idTelemetry, out CyclycArray<TDto>? cacheItem))
|
if(!caches.TryGetValue(idTelemetry, out TelemetryDataCacheItem? cacheItem))
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
if (cacheItem is null || !cacheItem.Any() || cacheItem[0].DateTime > dateBegin)
|
var cacheLastData = cacheItem.LastData;
|
||||||
|
|
||||||
|
if (!cacheLastData.Any() || cacheLastData[0].DateTime > dateBegin)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
var dateEnd = dateBegin.AddSeconds(intervalSec);
|
var dateEnd = dateBegin.AddSeconds(intervalSec);
|
||||||
var items = cacheItem
|
var items = cacheLastData
|
||||||
.Where(i => i.DateTime >= dateBegin && i.DateTime <= dateEnd);
|
.Where(i => i.DateTime >= dateBegin && i.DateTime <= dateEnd);
|
||||||
|
|
||||||
var ratio = items.Count() / approxPointsCount;
|
var ratio = items.Count() / approxPointsCount;
|
||||||
@ -116,19 +125,43 @@ namespace AsbCloudInfrastructure.Services.SAUB
|
|||||||
return items;
|
return items;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void InitializeCacheFromDB<TEntity>(IAsbCloudDbContext db)
|
public TDto? GetLastOrDefault(int idTelemetry)
|
||||||
where TEntity : class, ITelemetryData
|
{
|
||||||
|
if (!caches.TryGetValue(idTelemetry, out TelemetryDataCacheItem? cacheItem))
|
||||||
|
return default;
|
||||||
|
|
||||||
|
return cacheItem.LastData.LastOrDefault();
|
||||||
|
}
|
||||||
|
|
||||||
|
public DatesRangeDto? GetOrDefaultDataDateRange(int idTelemetry)
|
||||||
|
{
|
||||||
|
if (!caches.TryGetValue(idTelemetry, out TelemetryDataCacheItem? cacheItem))
|
||||||
|
return null;
|
||||||
|
|
||||||
|
var from = cacheItem.FirstByDate?.DateTime;
|
||||||
|
if(!cacheItem.LastData.Any())
|
||||||
|
return null;
|
||||||
|
|
||||||
|
var to = cacheItem.LastData[^1].DateTime;
|
||||||
|
from = from ?? cacheItem.LastData[0].DateTime;
|
||||||
|
|
||||||
|
return new DatesRangeDto { From = from.Value, To = to };
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task InitializeCacheFromDBAsync<TEntity>(IAsbCloudDbContext db, CancellationToken token)
|
||||||
|
where TEntity : class, AsbCloudDb.Model.ITelemetryData
|
||||||
{
|
{
|
||||||
if (isLoading)
|
if (isLoading)
|
||||||
throw new Exception("Multiple cache loading detected.");
|
throw new Exception("Multiple cache loading detected.");
|
||||||
|
|
||||||
isLoading = true;
|
isLoading = true;
|
||||||
Well[] wells = Array.Empty<Well>();
|
Well[] wells = Array.Empty<Well>();
|
||||||
wells = db.Set<Well>()
|
|
||||||
.Include(well => well.Telemetry)
|
wells = await db.Set<Well>()
|
||||||
.Include(well => well.Cluster)
|
.Include(well => well.Telemetry)
|
||||||
.Where(well => well.IdTelemetry != null)
|
.Include(well => well.Cluster)
|
||||||
.ToArray();
|
.Where(well => well.IdTelemetry != null)
|
||||||
|
.ToArrayAsync(token);
|
||||||
|
|
||||||
foreach (Well well in wells)
|
foreach (Well well in wells)
|
||||||
{
|
{
|
||||||
@ -139,46 +172,61 @@ namespace AsbCloudInfrastructure.Services.SAUB
|
|||||||
var idTelemetry = well.IdTelemetry!.Value;
|
var idTelemetry = well.IdTelemetry!.Value;
|
||||||
var hoursOffset = well.Timezone.Hours;
|
var hoursOffset = well.Timezone.Hours;
|
||||||
|
|
||||||
IEnumerable<TDto> cacheItemData = GetCacheDataFromDb<TEntity>(db, idTelemetry, capacity, hoursOffset);
|
var cacheItem = await GetOrDefaultCacheDataFromDbAsync<TEntity>(db, idTelemetry, capacity, hoursOffset, token);
|
||||||
var cacheItem = new CyclycArray<TDto>(capacity);
|
if(cacheItem is not null)
|
||||||
cacheItem.AddRange(cacheItemData);
|
{
|
||||||
caches.TryAdd(idTelemetry, cacheItem);
|
caches.TryAdd(idTelemetry, cacheItem);
|
||||||
|
System.Diagnostics.Trace.TraceInformation($"cache<{typeof(TDto).Name}> for well: {well.Cluster?.Caption}/{well.Caption} loaded");
|
||||||
System.Diagnostics.Trace.TraceInformation($"cache<{typeof(TDto).Name}> for well: {well.Cluster?.Caption}/{well.Caption} loaded");
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
System.Diagnostics.Trace.TraceInformation($"cache<{typeof(TDto).Name}> for well: {well.Cluster?.Caption}/{well.Caption} has no data");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
System.Diagnostics.Trace.TraceInformation($"cache<{typeof(TDto).Name}> load complete");
|
System.Diagnostics.Trace.TraceInformation($"cache<{typeof(TDto).Name}> load complete");
|
||||||
isLoading = false;
|
isLoading = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static IAsbCloudDbContext MakeContext(IConfiguration configuration)
|
private static async Task<TelemetryDataCacheItem?> GetOrDefaultCacheDataFromDbAsync<TEntity>(IAsbCloudDbContext db, int idTelemetry, int capacity, double hoursOffset, CancellationToken token)
|
||||||
|
where TEntity : class, AsbCloudDb.Model.ITelemetryData
|
||||||
{
|
{
|
||||||
var connectionString = configuration.GetConnectionString("DefaultConnection");
|
var query = db.Set<TEntity>()
|
||||||
var options = new DbContextOptionsBuilder<AsbCloudDbContext>()
|
.Where(i => i.IdTelemetry == idTelemetry);
|
||||||
.UseNpgsql(connectionString)
|
|
||||||
.Options;
|
|
||||||
var db = new AsbCloudDbContext(options);
|
|
||||||
return db;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static IEnumerable<TDto> GetCacheDataFromDb<TEntity>(IAsbCloudDbContext db, int idTelemetry, int capacity, double hoursOffset)
|
var firstDbEntity = await query
|
||||||
where TEntity : class, ITelemetryData
|
.OrderBy(i => i.DateTime)
|
||||||
{
|
.FirstOrDefaultAsync(token);
|
||||||
var entities = db.Set<TEntity>()
|
|
||||||
.Where(i => i.IdTelemetry == idTelemetry)
|
if (firstDbEntity is null)
|
||||||
|
return default;
|
||||||
|
|
||||||
|
var first = firstDbEntity.Adapt<TDto>();
|
||||||
|
first.DateTime = firstDbEntity.DateTime.ToRemoteDateTime(hoursOffset);
|
||||||
|
|
||||||
|
var entities = await query
|
||||||
.OrderByDescending(i => i.DateTime)
|
.OrderByDescending(i => i.DateTime)
|
||||||
.Take(capacity)
|
.Take(capacity)
|
||||||
.ToArray()
|
.ToArrayAsync(token);
|
||||||
|
|
||||||
|
var dtos = entities
|
||||||
.AsEnumerable()
|
.AsEnumerable()
|
||||||
.Reverse();
|
.Reverse()
|
||||||
|
.Select(entity => {
|
||||||
|
var dto = entity.Adapt<TDto>();
|
||||||
|
dto.DateTime = entity.DateTime.ToRemoteDateTime(hoursOffset);
|
||||||
|
return dto;
|
||||||
|
});
|
||||||
|
|
||||||
var dtos = entities.Select(entity => {
|
var cacheItem = new CyclycArray<TDto>(capacity);
|
||||||
var dto = entity.Adapt<TDto>();
|
cacheItem.AddRange(dtos);
|
||||||
dto.DateTime = entity.DateTime.ToRemoteDateTime(hoursOffset);
|
|
||||||
return dto;
|
|
||||||
});
|
|
||||||
|
|
||||||
return dtos;
|
var item = new TelemetryDataCacheItem
|
||||||
|
{
|
||||||
|
FirstByDate = first,
|
||||||
|
LastData = cacheItem,
|
||||||
|
};
|
||||||
|
return item;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,21 +19,20 @@ namespace AsbCloudInfrastructure.Services.SAUB
|
|||||||
{
|
{
|
||||||
private readonly IAsbCloudDbContext db;
|
private readonly IAsbCloudDbContext db;
|
||||||
private readonly IMemoryCache memoryCache;
|
private readonly IMemoryCache memoryCache;
|
||||||
private readonly ITelemetryTracker telemetryTracker;
|
private readonly TelemetryDataCache<TelemetryDataSaubDto> dataSaubCache;
|
||||||
private readonly ITimezoneService timezoneService;
|
private readonly ITimezoneService timezoneService;
|
||||||
|
|
||||||
public ITimezoneService TimeZoneService => timezoneService;
|
public ITimezoneService TimeZoneService => timezoneService;
|
||||||
public ITelemetryTracker TelemetryTracker => telemetryTracker;
|
|
||||||
|
|
||||||
public TelemetryService(
|
public TelemetryService(
|
||||||
IAsbCloudDbContext db,
|
IAsbCloudDbContext db,
|
||||||
IMemoryCache memoryCache,
|
IMemoryCache memoryCache,
|
||||||
ITelemetryTracker telemetryTracker,
|
TelemetryDataCache<TelemetryDataSaubDto> dataSaubCache,
|
||||||
ITimezoneService timezoneService)
|
ITimezoneService timezoneService)
|
||||||
{
|
{
|
||||||
this.db = db;
|
this.db = db;
|
||||||
this.memoryCache = memoryCache;
|
this.memoryCache = memoryCache;
|
||||||
this.telemetryTracker = telemetryTracker;
|
this.dataSaubCache = dataSaubCache;
|
||||||
this.timezoneService = timezoneService;
|
this.timezoneService = timezoneService;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -47,34 +46,11 @@ namespace AsbCloudInfrastructure.Services.SAUB
|
|||||||
memoryCache.DropBasic<Telemetry>();
|
memoryCache.DropBasic<Telemetry>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public DateTime GetLastTelemetryDate(int idTelemetry)
|
|
||||||
{
|
|
||||||
var telemetry = GetTelemetryCache().FirstOrDefault(t => t.Id == idTelemetry);
|
|
||||||
|
|
||||||
if (telemetry is null)
|
|
||||||
throw new Exception($"Telemetry id:{idTelemetry} does not exist");
|
|
||||||
|
|
||||||
var uid = telemetry.RemoteUid;
|
|
||||||
var timzone = GetTimezone(idTelemetry);
|
|
||||||
var lastTelemetryDate = telemetryTracker.GetLastTelemetryDateByUid(uid);
|
|
||||||
return lastTelemetryDate.ToRemoteDateTime(timzone.Hours);
|
|
||||||
}
|
|
||||||
|
|
||||||
public DatesRangeDto GetDatesRange(int idTelemetry)
|
public DatesRangeDto GetDatesRange(int idTelemetry)
|
||||||
{
|
{
|
||||||
var telemetry = GetTelemetryCache().FirstOrDefault(t => t.Id == idTelemetry);
|
var cacheDataRange = dataSaubCache.GetOrDefaultDataDateRange(idTelemetry)
|
||||||
if (telemetry is null)
|
?? new ();
|
||||||
throw new Exception($"Telemetry id:{idTelemetry} does not exist");
|
return cacheDataRange;
|
||||||
|
|
||||||
var dto = TelemetryTracker.GetTelemetryDateRangeByUid(telemetry.RemoteUid);
|
|
||||||
if (dto is null)
|
|
||||||
throw new Exception($"Telemetry id:{idTelemetry} has no data");
|
|
||||||
|
|
||||||
var timezone = GetTimezone(idTelemetry);
|
|
||||||
dto.From = dto.From.ToTimeZoneOffsetHours(timezone.Hours);
|
|
||||||
dto.To = dto.To.ToTimeZoneOffsetHours(timezone.Hours);
|
|
||||||
|
|
||||||
return dto;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public int GetOrCreateTelemetryIdByUid(string uid)
|
public int GetOrCreateTelemetryIdByUid(string uid)
|
||||||
|
@ -1,156 +0,0 @@
|
|||||||
using AsbCloudApp.Data;
|
|
||||||
using AsbCloudApp.Services;
|
|
||||||
using AsbCloudDb.Model;
|
|
||||||
using Microsoft.EntityFrameworkCore;
|
|
||||||
using Microsoft.Extensions.Caching.Memory;
|
|
||||||
using Microsoft.Extensions.Configuration;
|
|
||||||
using System;
|
|
||||||
using System.Collections.Concurrent;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace AsbCloudInfrastructure.Services.SAUB
|
|
||||||
{
|
|
||||||
|
|
||||||
public class TelemetryTracker : ITelemetryTracker
|
|
||||||
{
|
|
||||||
class TrackerStat
|
|
||||||
{
|
|
||||||
//public int Id { get; set; }
|
|
||||||
|
|
||||||
public string RemoteUid { get; set; } = null!;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Время последнего запроса (по времени сервера)
|
|
||||||
/// </summary>
|
|
||||||
public DateTimeOffset LastTimeServer { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Дата первых данных в БД
|
|
||||||
/// </summary>
|
|
||||||
public DateTimeOffset TelemetryDateUtcMin { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Дата последних данных в БД
|
|
||||||
/// </summary>
|
|
||||||
public DateTimeOffset TelemetryDateUtcMax { get; set; }
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private readonly ConcurrentDictionary<string, TrackerStat> telemetriesStats;
|
|
||||||
|
|
||||||
public TelemetryTracker(IConfiguration configuration, IMemoryCache memoryCache)
|
|
||||||
{
|
|
||||||
// TODO: make this background work
|
|
||||||
var contextOptions = new DbContextOptionsBuilder<AsbCloudDbContext>()
|
|
||||||
.UseNpgsql(configuration.GetConnectionString("DefaultConnection"))
|
|
||||||
.Options;
|
|
||||||
var db = new AsbCloudDbContext(contextOptions);
|
|
||||||
|
|
||||||
var cacheTelemetry = memoryCache.GetOrCreateBasic(db.Set<Telemetry>().Include(t=>t.Well));
|
|
||||||
var keyValuePairs = new Dictionary<string, TrackerStat>(cacheTelemetry.Count());
|
|
||||||
foreach (var telemetry in cacheTelemetry)
|
|
||||||
{
|
|
||||||
var date = telemetry.Info?.DrillingStartDate
|
|
||||||
?? ParseDateFromUidOrDefault(telemetry.RemoteUid, DateTimeOffset.MinValue);
|
|
||||||
|
|
||||||
keyValuePairs[telemetry.RemoteUid] = new TrackerStat
|
|
||||||
{
|
|
||||||
RemoteUid = telemetry.RemoteUid,
|
|
||||||
TelemetryDateUtcMin = date,
|
|
||||||
TelemetryDateUtcMax = date,
|
|
||||||
LastTimeServer = date,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
telemetriesStats = new ConcurrentDictionary<string, TrackerStat>(keyValuePairs);
|
|
||||||
|
|
||||||
Task.Run(async () =>
|
|
||||||
{
|
|
||||||
db.Database.SetCommandTimeout(2 * 60);
|
|
||||||
var dates = await db.TelemetryDataSaub
|
|
||||||
.GroupBy(d => d.IdTelemetry)
|
|
||||||
.Select(g => new
|
|
||||||
{
|
|
||||||
IdTelemetry = g.Key,
|
|
||||||
DateMax = g.Max(d => d.DateTime),
|
|
||||||
DateMin = g.Min(d => d.DateTime),
|
|
||||||
})
|
|
||||||
.AsNoTracking()
|
|
||||||
.ToListAsync()
|
|
||||||
.ConfigureAwait(false);
|
|
||||||
|
|
||||||
var oldRequests = dates.Select(t => new
|
|
||||||
{
|
|
||||||
Uid = cacheTelemetry.FirstOrDefault(c => c.Id == t.IdTelemetry)?.RemoteUid,
|
|
||||||
t.DateMax,
|
|
||||||
t.DateMin,
|
|
||||||
}).Where(s => !string.IsNullOrEmpty(s.Uid));
|
|
||||||
|
|
||||||
foreach (var oldReq in oldRequests)
|
|
||||||
{
|
|
||||||
if (oldReq.Uid is not null)
|
|
||||||
{
|
|
||||||
var telemetryStat = telemetriesStats.GetOrAdd(oldReq.Uid, (uid) => new TrackerStat { RemoteUid = uid });
|
|
||||||
telemetryStat.TelemetryDateUtcMin = oldReq.DateMin;
|
|
||||||
telemetryStat.TelemetryDateUtcMax = oldReq.DateMax;
|
|
||||||
telemetryStat.LastTimeServer = oldReq.DateMax;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}).ContinueWith((t) =>
|
|
||||||
{
|
|
||||||
db.Dispose();
|
|
||||||
return t;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private static DateTimeOffset ParseDateFromUidOrDefault(string remoteUid, DateTimeOffset defaultValue = default)
|
|
||||||
{
|
|
||||||
//example: uid = 20211102_173407926
|
|
||||||
if (string.IsNullOrEmpty(remoteUid) || remoteUid.Length != 18)
|
|
||||||
return defaultValue;
|
|
||||||
|
|
||||||
if (DateTime.TryParseExact(remoteUid, "yyyyMMdd_HHmmssfff",
|
|
||||||
System.Globalization.CultureInfo.InvariantCulture,
|
|
||||||
System.Globalization.DateTimeStyles.AssumeUniversal,
|
|
||||||
out DateTime parsedDate))
|
|
||||||
return parsedDate;
|
|
||||||
|
|
||||||
return defaultValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SaveRequestDate(string uid, DateTimeOffset remoteDate)
|
|
||||||
{
|
|
||||||
var stat = telemetriesStats.GetOrAdd(uid, _ => new TrackerStat
|
|
||||||
{
|
|
||||||
RemoteUid = uid,
|
|
||||||
TelemetryDateUtcMin = remoteDate
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
stat.LastTimeServer = DateTime.Now;
|
|
||||||
|
|
||||||
if (stat.TelemetryDateUtcMax.ToUniversalTime() < remoteDate.ToUniversalTime())
|
|
||||||
stat.TelemetryDateUtcMax = remoteDate;
|
|
||||||
}
|
|
||||||
|
|
||||||
public DateTimeOffset GetLastTelemetryDateByUid(string uid) =>
|
|
||||||
telemetriesStats.GetValueOrDefault(uid)?.TelemetryDateUtcMax ?? default;
|
|
||||||
|
|
||||||
public DatesRangeDto GetTelemetryDateRangeByUid(string uid)
|
|
||||||
{
|
|
||||||
var stat = telemetriesStats.GetValueOrDefault(uid);
|
|
||||||
var range = new DatesRangeDto
|
|
||||||
{
|
|
||||||
From = stat?.TelemetryDateUtcMin.UtcDateTime ?? default,
|
|
||||||
To = stat?.TelemetryDateUtcMax.UtcDateTime ?? default,
|
|
||||||
};
|
|
||||||
return range;
|
|
||||||
}
|
|
||||||
|
|
||||||
public IEnumerable<string> GetTransmittingTelemetriesUids() =>
|
|
||||||
telemetriesStats.Keys;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,13 +1,14 @@
|
|||||||
using AsbCloudApp.Data;
|
using AsbCloudApp.Data;
|
||||||
using AsbCloudApp.Data.ProcessMap;
|
using AsbCloudApp.Data.ProcessMap;
|
||||||
|
using AsbCloudApp.Data.SAUB;
|
||||||
using AsbCloudApp.Repositories;
|
using AsbCloudApp.Repositories;
|
||||||
using AsbCloudApp.Requests;
|
using AsbCloudApp.Requests;
|
||||||
using AsbCloudApp.Services;
|
using AsbCloudApp.Services;
|
||||||
using AsbCloudApp.Services.Subsystems;
|
using AsbCloudApp.Services.Subsystems;
|
||||||
using AsbCloudDb.Model;
|
using AsbCloudDb.Model;
|
||||||
using AsbCloudInfrastructure.Background;
|
using AsbCloudInfrastructure.Background;
|
||||||
|
using AsbCloudInfrastructure.Services.SAUB;
|
||||||
using Mapster;
|
using Mapster;
|
||||||
using Microsoft.EntityFrameworkCore;
|
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
@ -46,6 +47,7 @@ namespace AsbCloudInfrastructure.Services
|
|||||||
var operationsStatService = serviceProvider.GetRequiredService<IOperationsStatService>();
|
var operationsStatService = serviceProvider.GetRequiredService<IOperationsStatService>();
|
||||||
var processMapRepository = serviceProvider.GetRequiredService<IProcessMapPlanRepository>();
|
var processMapRepository = serviceProvider.GetRequiredService<IProcessMapPlanRepository>();
|
||||||
var subsystemOperationTimeService = serviceProvider.GetRequiredService<ISubsystemOperationTimeService>();
|
var subsystemOperationTimeService = serviceProvider.GetRequiredService<ISubsystemOperationTimeService>();
|
||||||
|
var telemetryDataSaubCache = serviceProvider.GetRequiredService<TelemetryDataCache<TelemetryDataSaubDto>>();
|
||||||
|
|
||||||
var activeWells = await wellService.GetAsync(new() {IdState = 1}, token);
|
var activeWells = await wellService.GetAsync(new() {IdState = 1}, token);
|
||||||
|
|
||||||
@ -56,21 +58,6 @@ namespace AsbCloudInfrastructure.Services
|
|||||||
.Where(w => w.IdTelemetry != null)
|
.Where(w => w.IdTelemetry != null)
|
||||||
.Select(t => t.IdTelemetry);
|
.Select(t => t.IdTelemetry);
|
||||||
|
|
||||||
var lastTelemetryInfo = await db.TelemetryDataSaub
|
|
||||||
.Where(t => idTelemetries.Contains(t.IdTelemetry))
|
|
||||||
.Select(t => new
|
|
||||||
{
|
|
||||||
t.IdTelemetry,
|
|
||||||
t.WellDepth,
|
|
||||||
t.DateTime,
|
|
||||||
})
|
|
||||||
.GroupBy(t => t.IdTelemetry)
|
|
||||||
.Select(g => g.OrderByDescending(t => t.DateTime)
|
|
||||||
.First()
|
|
||||||
)
|
|
||||||
.AsNoTracking()
|
|
||||||
.ToArrayAsync(token);
|
|
||||||
|
|
||||||
var processMapRequests = activeWellsIds.Select(id => new ProcessMapRequest { IdWell = id });
|
var processMapRequests = activeWellsIds.Select(id => new ProcessMapRequest { IdWell = id });
|
||||||
var processMaps = await processMapRepository.GetProcessMapAsync(processMapRequests, token);
|
var processMaps = await processMapRepository.GetProcessMapAsync(processMapRequests, token);
|
||||||
|
|
||||||
@ -83,43 +70,53 @@ namespace AsbCloudInfrastructure.Services
|
|||||||
});
|
});
|
||||||
|
|
||||||
var operationsStat = await operationsStatService.GetWellsStatAsync(activeWellsIds, token);
|
var operationsStat = await operationsStatService.GetWellsStatAsync(activeWellsIds, token);
|
||||||
|
|
||||||
var subsystemStat = await subsystemOperationTimeService.GetStatByActiveWells(activeWellsIds, token);
|
var subsystemStat = await subsystemOperationTimeService.GetStatByActiveWells(activeWellsIds, token);
|
||||||
|
|
||||||
WellMapInfo = activeWells.Select(well => {
|
WellMapInfo = activeWells.Select(well => {
|
||||||
var wellMapInfo = well.Adapt<WellMapInfoWithComanies>();
|
var wellMapInfo = well.Adapt<WellMapInfoWithComanies>();
|
||||||
|
|
||||||
var wellLastTelemetryInfo = lastTelemetryInfo.FirstOrDefault(t => t.IdTelemetry == well.IdTelemetry);
|
|
||||||
|
|
||||||
var wellOperationsStat = operationsStat.FirstOrDefault(s => s.Id == well.Id);
|
var wellOperationsStat = operationsStat.FirstOrDefault(s => s.Id == well.Id);
|
||||||
var wellLastFactSection = wellOperationsStat?.Sections.LastOrDefault(s => s.Fact is not null);
|
var wellLastFactSection = wellOperationsStat?.Sections.LastOrDefault(s => s.Fact is not null);
|
||||||
|
|
||||||
var wellSubsystemStat = subsystemStat.FirstOrDefault(s => s.Well.Id == well.Id);
|
double? currentDepth = null;
|
||||||
|
double? planTotalDepth = null;
|
||||||
|
DateTime lastTelemetryDate = default;
|
||||||
|
|
||||||
double currentDepth = wellLastTelemetryInfo?.WellDepth
|
if (well.IdTelemetry.HasValue)
|
||||||
?? wellLastFactSection?.Fact?.WellDepthEnd
|
{
|
||||||
?? 0d;
|
var lastSaubTelemetry = telemetryDataSaubCache.GetLastOrDefault(well.IdTelemetry.Value);
|
||||||
|
if(lastSaubTelemetry is not null)
|
||||||
|
{
|
||||||
|
currentDepth = lastSaubTelemetry.WellDepth;
|
||||||
|
lastTelemetryDate = lastSaubTelemetry.DateTime;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
currentDepth ??= wellLastFactSection?.Fact?.WellDepthEnd;
|
||||||
|
|
||||||
var wellProcessMaps = processMaps
|
var wellProcessMaps = processMaps
|
||||||
.Where(p => p.IdWell == well.Id)
|
.Where(p => p.IdWell == well.Id)
|
||||||
.OrderBy(p => p.DepthEnd);
|
.OrderBy(p => p.DepthEnd);
|
||||||
|
|
||||||
int? idSection = wellLastFactSection?.Id;
|
int? idSection = wellLastFactSection?.Id;
|
||||||
|
ProcessMapPlanDto? welllProcessMap = null;
|
||||||
|
|
||||||
ProcessMapPlanDto? welllProcessMap;
|
if (idSection.HasValue)
|
||||||
if (idSection is not null)
|
|
||||||
{
|
{
|
||||||
welllProcessMap = wellProcessMaps.FirstOrDefault(p => p.IdWellSectionType == idSection);
|
welllProcessMap = wellProcessMaps.FirstOrDefault(p => p.IdWellSectionType == idSection);
|
||||||
}
|
}
|
||||||
else
|
else if(currentDepth.HasValue)
|
||||||
{
|
{
|
||||||
welllProcessMap = wellProcessMaps.FirstOrDefault(p => p.DepthStart <= currentDepth && p.DepthEnd >= currentDepth);
|
welllProcessMap = wellProcessMaps.FirstOrDefault(p => p.DepthStart <= currentDepth.Value && p.DepthEnd >= currentDepth.Value);
|
||||||
idSection ??= welllProcessMap?.IdWellSectionType;
|
idSection ??= welllProcessMap?.IdWellSectionType;
|
||||||
}
|
}
|
||||||
|
|
||||||
wellMapInfo.LastTelemetryDate = wellLastTelemetryInfo?.DateTime.ToRemoteDateTime(5) ?? new DateTime();
|
planTotalDepth = wellDepthByProcessMap.FirstOrDefault(p => p.Id == well.Id)?.DepthEnd;
|
||||||
|
planTotalDepth ??= wellOperationsStat?.Total.Plan?.WellDepthEnd;
|
||||||
|
|
||||||
wellMapInfo.WellDepth = new()
|
wellMapInfo.WellDepth = new()
|
||||||
{
|
{
|
||||||
Plan = wellDepthByProcessMap.FirstOrDefault(p => p.Id == well.Id)?.DepthEnd,
|
Plan = planTotalDepth,
|
||||||
Fact = currentDepth,
|
Fact = currentDepth,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -135,6 +132,7 @@ namespace AsbCloudInfrastructure.Services
|
|||||||
Fact = wellOperationsStat?.Total.Fact?.RouteSpeed,
|
Fact = wellOperationsStat?.Total.Fact?.RouteSpeed,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var wellSubsystemStat = subsystemStat.FirstOrDefault(s => s.Well.Id == well.Id);
|
||||||
wellMapInfo.SaubUsage = wellSubsystemStat?.SubsystemAKB?.KUsage ?? 0d;
|
wellMapInfo.SaubUsage = wellSubsystemStat?.SubsystemAKB?.KUsage ?? 0d;
|
||||||
wellMapInfo.SpinUsage = wellSubsystemStat?.SubsystemSpinMaster?.KUsage ?? 0d;
|
wellMapInfo.SpinUsage = wellSubsystemStat?.SubsystemSpinMaster?.KUsage ?? 0d;
|
||||||
wellMapInfo.TvdLagPercent = wellOperationsStat?.TvdLagDays ?? 0d;
|
wellMapInfo.TvdLagPercent = wellOperationsStat?.TvdLagDays ?? 0d;
|
||||||
|
@ -151,7 +151,7 @@ namespace AsbCloudInfrastructure.Services.WellOperationService
|
|||||||
WellType = wellType?.Caption ?? "",
|
WellType = wellType?.Caption ?? "",
|
||||||
IdState = well.IdState,
|
IdState = well.IdState,
|
||||||
State = wellService.GetStateText(well.IdState),
|
State = wellService.GetStateText(well.IdState),
|
||||||
LastTelemetryDate = wellService.GetLastTelemetryDate(well.Id).DateTime,
|
LastTelemetryDate = wellService.GetLastTelemetryDate(well.Id),
|
||||||
Companies = await wellService.GetCompaniesAsync(well.Id, token)
|
Companies = await wellService.GetCompaniesAsync(well.Id, token)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -57,15 +57,15 @@ namespace AsbCloudInfrastructure.Services
|
|||||||
private void DropCacheRelationCompanyWell()
|
private void DropCacheRelationCompanyWell()
|
||||||
=> memoryCache.DropBasic<RelationCompanyWell>();
|
=> memoryCache.DropBasic<RelationCompanyWell>();
|
||||||
|
|
||||||
public DateTimeOffset GetLastTelemetryDate(int idWell)
|
public DateTime GetLastTelemetryDate(int idWell)
|
||||||
{
|
{
|
||||||
var well = GetOrDefault(idWell);
|
var well = GetOrDefault(idWell);
|
||||||
|
|
||||||
if (well?.IdTelemetry is null)
|
if (well?.IdTelemetry is null)
|
||||||
return DateTimeOffset.MinValue;
|
return DateTime.MinValue;
|
||||||
|
|
||||||
var lastTelemetryDate = telemetryService.GetLastTelemetryDate((int)well.IdTelemetry);
|
var datesRange = telemetryService.GetDatesRange(well.IdTelemetry.Value);
|
||||||
return lastTelemetryDate;
|
return datesRange.To;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
@ -97,7 +97,7 @@ namespace AsbCloudInfrastructure.Services
|
|||||||
dto.Latitude ??= gCluster.Key.Latitude ?? gDeposit.Key.Latitude;
|
dto.Latitude ??= gCluster.Key.Latitude ?? gDeposit.Key.Latitude;
|
||||||
dto.Longitude ??= gCluster.Key.Longitude ?? gDeposit.Key.Longitude;
|
dto.Longitude ??= gCluster.Key.Longitude ?? gDeposit.Key.Longitude;
|
||||||
if (well.IdTelemetry is not null)
|
if (well.IdTelemetry is not null)
|
||||||
dto.LastTelemetryDate = telemetryService.GetLastTelemetryDate(well.IdTelemetry.Value);
|
dto.LastTelemetryDate = telemetryService.GetDatesRange(well.IdTelemetry.Value).To;
|
||||||
|
|
||||||
return dto;
|
return dto;
|
||||||
}),
|
}),
|
||||||
@ -256,7 +256,7 @@ namespace AsbCloudInfrastructure.Services
|
|||||||
dto.Cluster = entity.Cluster.Caption;
|
dto.Cluster = entity.Cluster.Caption;
|
||||||
dto.Deposit = entity.Cluster.Deposit.Caption;
|
dto.Deposit = entity.Cluster.Deposit.Caption;
|
||||||
if (entity.IdTelemetry is not null)
|
if (entity.IdTelemetry is not null)
|
||||||
dto.LastTelemetryDate = telemetryService.GetLastTelemetryDate((int)entity.IdTelemetry);
|
dto.LastTelemetryDate = telemetryService.GetDatesRange(entity.IdTelemetry.Value).To;
|
||||||
dto.Companies = entity.RelationCompaniesWells
|
dto.Companies = entity.RelationCompaniesWells
|
||||||
.Select(r => Convert(r.Company))
|
.Select(r => Convert(r.Company))
|
||||||
.ToList();
|
.ToList();
|
||||||
|
@ -10,6 +10,8 @@ using System;
|
|||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using AsbCloudInfrastructure.Background;
|
using AsbCloudInfrastructure.Background;
|
||||||
|
using AsbCloudApp.Data.SAUB;
|
||||||
|
using AsbCloudInfrastructure.Services.SAUB;
|
||||||
|
|
||||||
namespace AsbCloudInfrastructure
|
namespace AsbCloudInfrastructure
|
||||||
{
|
{
|
||||||
@ -28,6 +30,9 @@ namespace AsbCloudInfrastructure
|
|||||||
var wellService = provider.GetRequiredService<IWellService>();
|
var wellService = provider.GetRequiredService<IWellService>();
|
||||||
wellService.EnshureTimezonesIsSetAsync(CancellationToken.None).Wait();// TODO: make this background work
|
wellService.EnshureTimezonesIsSetAsync(CancellationToken.None).Wait();// TODO: make this background work
|
||||||
|
|
||||||
|
_ = provider.GetRequiredService<TelemetryDataCache<TelemetryDataSaubDto>>();
|
||||||
|
_ = provider.GetRequiredService<TelemetryDataCache<TelemetryDataSpinDto>>();
|
||||||
|
|
||||||
var backgroundWorker = provider.GetRequiredService<BackgroundWorker>();
|
var backgroundWorker = provider.GetRequiredService<BackgroundWorker>();
|
||||||
backgroundWorker.Push(WellInfoService.MakeWork());
|
backgroundWorker.Push(WellInfoService.MakeWork());
|
||||||
backgroundWorker.Push(OperationDetectionWorkFactory.MakeWork());
|
backgroundWorker.Push(OperationDetectionWorkFactory.MakeWork());
|
||||||
@ -45,7 +50,7 @@ namespace AsbCloudInfrastructure
|
|||||||
var workAction = (string _, IServiceProvider _, CancellationToken _) => {
|
var workAction = (string _, IServiceProvider _, CancellationToken _) => {
|
||||||
var bytes = GC.GetTotalMemory(false);
|
var bytes = GC.GetTotalMemory(false);
|
||||||
var bytesString = FromatBytes(bytes);
|
var bytesString = FromatBytes(bytes);
|
||||||
System.Diagnostics.Trace.TraceInformation($"Total memory allocated is {bytesString} bytes. DbContext count is:{AsbCloudDb.Model.AsbCloudDbContext.ReferenceCount}");
|
System.Diagnostics.Trace.TraceInformation($"Total memory allocated is {bytesString} bytes. DbContext count is:{AsbCloudDbContext.ReferenceCount}");
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
};
|
};
|
||||||
var workPeriod = TimeSpan.FromMinutes(1);
|
var workPeriod = TimeSpan.FromMinutes(1);
|
||||||
|
Loading…
Reference in New Issue
Block a user