diff --git a/AsbCloudApp/Services/ITelemetryService.cs b/AsbCloudApp/Services/ITelemetryService.cs
index 2e6592b4..c46a32ec 100644
--- a/AsbCloudApp/Services/ITelemetryService.cs
+++ b/AsbCloudApp/Services/ITelemetryService.cs
@@ -16,11 +16,6 @@ namespace AsbCloudApp.Services
///
ITimezoneService TimeZoneService { get; }
- ///
- /// трекер запросов
- ///
- ITelemetryTracker TelemetryTracker { get; }
-
///
/// получить idWell по uid телеметрии
///
@@ -42,13 +37,6 @@ namespace AsbCloudApp.Services
///
SimpleTimezoneDto GetTimezone(int idTelemetry);
- ///
- /// Получить дату получения последних данных
- ///
- ///
- ///
- DateTime GetLastTelemetryDate(int idTelemetry);
-
///
/// получить idTelemetry по IdWell
///
diff --git a/AsbCloudApp/Services/ITelemetryTracker.cs b/AsbCloudApp/Services/ITelemetryTracker.cs
deleted file mode 100644
index ae9acb80..00000000
--- a/AsbCloudApp/Services/ITelemetryTracker.cs
+++ /dev/null
@@ -1,39 +0,0 @@
-using AsbCloudApp.Data;
-using System;
-using System.Collections.Generic;
-
-namespace AsbCloudApp.Services
-{
- ///
- /// Сервис статистики телеметрии
- ///
- public interface ITelemetryTracker
- {
- ///
- /// получить дату последней отправки данных панелью
- ///
- ///
- ///
- DateTimeOffset GetLastTelemetryDateByUid(string uid);
-
- ///
- /// получить диапазон дат за которые есть данные по телеметрии
- ///
- ///
- ///
- DatesRangeDto GetTelemetryDateRangeByUid(string uid);
-
- ///
- /// список передающих телеметрий
- ///
- ///
- IEnumerable GetTransmittingTelemetriesUids();
-
- ///
- /// обновить статистику по телеметрии
- ///
- ///
- ///
- void SaveRequestDate(string uid, DateTimeOffset remoteDate);
- }
-}
diff --git a/AsbCloudApp/Services/IWellService.cs b/AsbCloudApp/Services/IWellService.cs
index 057b3444..eb8d9f37 100644
--- a/AsbCloudApp/Services/IWellService.cs
+++ b/AsbCloudApp/Services/IWellService.cs
@@ -63,7 +63,7 @@ namespace AsbCloudApp.Services
///
///
///
- DateTimeOffset GetLastTelemetryDate(int idWell);
+ DateTime GetLastTelemetryDate(int idWell);
//TODO: выяснить и удалить отсюда
///
diff --git a/AsbCloudApp/Services/InstantDataRepository.cs b/AsbCloudApp/Services/InstantDataRepository.cs
deleted file mode 100644
index d58e602e..00000000
--- a/AsbCloudApp/Services/InstantDataRepository.cs
+++ /dev/null
@@ -1,12 +0,0 @@
-using System;
-using System.Collections.Concurrent;
-
-namespace AsbCloudApp.Services
-{
- ///
- /// Репозиторий для хранения в оперативке данных (от панели)
- ///
- public class InstantDataRepository : ConcurrentDictionary>
- {
- }
-}
diff --git a/AsbCloudInfrastructure/DependencyInjection.cs b/AsbCloudInfrastructure/DependencyInjection.cs
index 1911d5a8..7ee76fe2 100644
--- a/AsbCloudInfrastructure/DependencyInjection.cs
+++ b/AsbCloudInfrastructure/DependencyInjection.cs
@@ -1,12 +1,10 @@
using AsbCloudApp.Data;
-using AsbCloudApp.Data.GTR;
using AsbCloudApp.Data.SAUB;
using AsbCloudApp.Data.Subsystems;
using AsbCloudApp.Repositories;
using AsbCloudApp.Services;
using AsbCloudApp.Services.Subsystems;
using AsbCloudDb.Model;
-using AsbCloudDb.Model.GTR;
using AsbCloudDb.Model.Subsystems;
using AsbCloudInfrastructure.Background;
using AsbCloudInfrastructure.Repository;
@@ -102,10 +100,8 @@ namespace AsbCloudInfrastructure
services.AddScoped();
services.AddSingleton(new WitsInfoService());
- services.AddSingleton(new InstantDataRepository());
- services.AddSingleton(provider=> TelemetryDataCache.GetInstance(configuration));
- services.AddSingleton(provider=> TelemetryDataCache.GetInstance(configuration));
- services.AddSingleton();
+ services.AddSingleton(provider => TelemetryDataCache.GetInstance(provider));
+ services.AddSingleton(provider => TelemetryDataCache.GetInstance(provider));
services.AddSingleton();
services.AddSingleton();
services.AddSingleton(provider => ReduceSamplingService.GetInstance(configuration));
diff --git a/AsbCloudInfrastructure/Repository/DepositRepository.cs b/AsbCloudInfrastructure/Repository/DepositRepository.cs
index 4944f79d..7f19f1d7 100644
--- a/AsbCloudInfrastructure/Repository/DepositRepository.cs
+++ b/AsbCloudInfrastructure/Repository/DepositRepository.cs
@@ -111,7 +111,7 @@ namespace AsbCloudInfrastructure.Repository
{
var dto = well.Adapt();
dto.WellType = well.WellType.Caption;
- dto.LastTelemetryDate = wellService.GetLastTelemetryDate(well.Id).DateTime;
+ dto.LastTelemetryDate = wellService.GetLastTelemetryDate(well.Id);
dto.Cluster = gCluster.Key.Caption;
dto.Deposit = gDeposit.Key.Caption;
return dto;
diff --git a/AsbCloudInfrastructure/Services/SAUB/TelemetryDataBaseService.cs b/AsbCloudInfrastructure/Services/SAUB/TelemetryDataBaseService.cs
index 3dea46b9..359efd18 100644
--- a/AsbCloudInfrastructure/Services/SAUB/TelemetryDataBaseService.cs
+++ b/AsbCloudInfrastructure/Services/SAUB/TelemetryDataBaseService.cs
@@ -64,7 +64,6 @@ namespace AsbCloudInfrastructure.Services.SAUB
});
var entityMaxDate = entities.Max(e => e.DateTime);
- telemetryService.TelemetryTracker.SaveRequestDate(uid, entityMaxDate);
var dbset = db.Set();
var stopwatch = Stopwatch.StartNew();
@@ -101,19 +100,15 @@ namespace AsbCloudInfrastructure.Services.SAUB
DateTimeOffset dateBeginUtc;
if (dateBegin == default)
{
- dateBeginUtc = telemetryService.GetLastTelemetryDate(telemetry.Id)
- .ToUtcDateTimeOffset(timezone.Hours);
- if (dateBeginUtc != default)
- dateBeginUtc = dateBeginUtc.AddSeconds(-intervalSec);
+ var dateRange = telemetryDataCache.GetOrDefaultDataDateRange(telemetry.Id);
+ dateBeginUtc = (dateRange?.To.ToUtcDateTimeOffset(timezone.Hours) ?? DateTime.UtcNow)
+ .AddSeconds(-intervalSec);
}
else
{
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);
if (cacheData is not null)
return cacheData;
diff --git a/AsbCloudInfrastructure/Services/SAUB/TelemetryDataCache.cs b/AsbCloudInfrastructure/Services/SAUB/TelemetryDataCache.cs
index f1b2186b..53089f17 100644
--- a/AsbCloudInfrastructure/Services/SAUB/TelemetryDataCache.cs
+++ b/AsbCloudInfrastructure/Services/SAUB/TelemetryDataCache.cs
@@ -7,17 +7,28 @@ using Microsoft.EntityFrameworkCore;
using Mapster;
using System.Threading.Tasks;
using Microsoft.Extensions.Configuration;
-
+using Microsoft.Extensions.DependencyInjection;
+using AsbCloudInfrastructure.Background;
+using System.Threading;
+using AsbCloudApp.Data;
namespace AsbCloudInfrastructure.Services.SAUB
{
public class TelemetryDataCache
where TDto : AsbCloudApp.Data.ITelemetryData
{
+ class TelemetryDataCacheItem
+ {
+ public TDto? FirstByDate { get; init; }
+ public CyclycArray LastData { get; init; } = null!;
+ }
+
+ private IServiceProvider provider = null!;
private const int activeWellCapacity = 12 * 60 * 60;
private const int doneWellCapacity = 65 * 60;
- private readonly ConcurrentDictionary> caches;
+ // key == idTelemetry
+ private readonly ConcurrentDictionary caches;
private bool isLoading = false;
private TelemetryDataCache()
@@ -27,35 +38,22 @@ namespace AsbCloudInfrastructure.Services.SAUB
private static TelemetryDataCache? instance;
- //TODO: Move initialize fromDB to bacground service task
- public static TelemetryDataCache GetInstance(IConfiguration configuration)
- where TEntity : class, ITelemetryData
+ public static TelemetryDataCache GetInstance(IServiceProvider provider)
+ where TEntity : class, AsbCloudDb.Model.ITelemetryData
{
if (instance is null)
{
instance = new TelemetryDataCache();
- _ = Task.Run(() =>
- {
- using var db = MakeContext(configuration);
- instance.InitializeCacheFromDB(db);
- db.Dispose();
+ var worker = provider.GetRequiredService();
+ var workId = $"Telemetry cache loading from DB {typeof(TEntity).Name}";
+ var work = new WorkBase(workId, async (workId, provider, token) => {
+ var db = provider.GetRequiredService();
+ await instance.InitializeCacheFromDBAsync(db, token);
});
+
+ worker.Push(work);
}
- return instance;
- }
- public static TelemetryDataCache GetInstance(IAsbCloudDbContext db, out Task initializationTask)
- where TEntity : class, ITelemetryData
- {
- if (instance is null)
- {
- instance = new TelemetryDataCache();
- initializationTask = Task.Run(() =>
- {
- instance.InitializeCacheFromDB(db);
- });
- }
- else
- initializationTask = Task.CompletedTask;
+ instance.provider = provider;
return instance;
}
@@ -66,24 +64,33 @@ namespace AsbCloudInfrastructure.Services.SAUB
///
public void AddRange(int idTelemetry, IEnumerable range)
{
- CyclycArray 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 (caches.TryGetValue(idTelemetry, out CyclycArray? localCacheItem))
+ if (caches.TryGetValue(idTelemetry, out TelemetryDataCacheItem? localCacheItem))
cacheItem = localCacheItem;
else
return;
}
else
{
- cacheItem = caches.GetOrAdd(idTelemetry, _ => new CyclycArray(activeWellCapacity));
+ cacheItem = caches.GetOrAdd(idTelemetry, _ => new TelemetryDataCacheItem()
+ {
+ FirstByDate = newItems.ElementAt(0),
+ LastData = new CyclycArray(activeWellCapacity)
+ });
}
-
- var newItems = range
- .OrderBy(i => i.DateTime);
- foreach (var item in newItems)
- item.IdTelemetry = idTelemetry;
- cacheItem.AddRange(newItems);
+
+ cacheItem.LastData.AddRange(newItems);
}
///
@@ -98,14 +105,16 @@ namespace AsbCloudInfrastructure.Services.SAUB
///
public IEnumerable? GetOrDefault(int idTelemetry, DateTime dateBegin, double intervalSec = 600d, int approxPointsCount = 1024)
{
- if(!caches.TryGetValue(idTelemetry, out CyclycArray? cacheItem))
+ if(!caches.TryGetValue(idTelemetry, out TelemetryDataCacheItem? cacheItem))
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;
var dateEnd = dateBegin.AddSeconds(intervalSec);
- var items = cacheItem
+ var items = cacheLastData
.Where(i => i.DateTime >= dateBegin && i.DateTime <= dateEnd);
var ratio = items.Count() / approxPointsCount;
@@ -116,19 +125,43 @@ namespace AsbCloudInfrastructure.Services.SAUB
return items;
}
- private void InitializeCacheFromDB(IAsbCloudDbContext db)
- where TEntity : class, ITelemetryData
+ public TDto? GetLastOrDefault(int idTelemetry)
+ {
+ 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(IAsbCloudDbContext db, CancellationToken token)
+ where TEntity : class, AsbCloudDb.Model.ITelemetryData
{
if (isLoading)
throw new Exception("Multiple cache loading detected.");
isLoading = true;
Well[] wells = Array.Empty();
- wells = db.Set()
- .Include(well => well.Telemetry)
- .Include(well => well.Cluster)
- .Where(well => well.IdTelemetry != null)
- .ToArray();
+
+ wells = await db.Set()
+ .Include(well => well.Telemetry)
+ .Include(well => well.Cluster)
+ .Where(well => well.IdTelemetry != null)
+ .ToArrayAsync(token);
foreach (Well well in wells)
{
@@ -139,46 +172,61 @@ namespace AsbCloudInfrastructure.Services.SAUB
var idTelemetry = well.IdTelemetry!.Value;
var hoursOffset = well.Timezone.Hours;
- IEnumerable cacheItemData = GetCacheDataFromDb(db, idTelemetry, capacity, hoursOffset);
- var cacheItem = new CyclycArray(capacity);
- cacheItem.AddRange(cacheItemData);
- caches.TryAdd(idTelemetry, cacheItem);
-
- System.Diagnostics.Trace.TraceInformation($"cache<{typeof(TDto).Name}> for well: {well.Cluster?.Caption}/{well.Caption} loaded");
+ var cacheItem = await GetOrDefaultCacheDataFromDbAsync(db, idTelemetry, capacity, hoursOffset, token);
+ if(cacheItem is not null)
+ {
+ caches.TryAdd(idTelemetry, cacheItem);
+ 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");
isLoading = false;
}
- private static IAsbCloudDbContext MakeContext(IConfiguration configuration)
+ private static async Task GetOrDefaultCacheDataFromDbAsync(IAsbCloudDbContext db, int idTelemetry, int capacity, double hoursOffset, CancellationToken token)
+ where TEntity : class, AsbCloudDb.Model.ITelemetryData
{
- var connectionString = configuration.GetConnectionString("DefaultConnection");
- var options = new DbContextOptionsBuilder()
- .UseNpgsql(connectionString)
- .Options;
- var db = new AsbCloudDbContext(options);
- return db;
- }
+ var query = db.Set()
+ .Where(i => i.IdTelemetry == idTelemetry);
- private static IEnumerable GetCacheDataFromDb(IAsbCloudDbContext db, int idTelemetry, int capacity, double hoursOffset)
- where TEntity : class, ITelemetryData
- {
- var entities = db.Set()
- .Where(i => i.IdTelemetry == idTelemetry)
+ var firstDbEntity = await query
+ .OrderBy(i => i.DateTime)
+ .FirstOrDefaultAsync(token);
+
+ if (firstDbEntity is null)
+ return default;
+
+ var first = firstDbEntity.Adapt();
+ first.DateTime = firstDbEntity.DateTime.ToRemoteDateTime(hoursOffset);
+
+ var entities = await query
.OrderByDescending(i => i.DateTime)
.Take(capacity)
- .ToArray()
+ .ToArrayAsync(token);
+
+ var dtos = entities
.AsEnumerable()
- .Reverse();
+ .Reverse()
+ .Select(entity => {
+ var dto = entity.Adapt();
+ dto.DateTime = entity.DateTime.ToRemoteDateTime(hoursOffset);
+ return dto;
+ });
- var dtos = entities.Select(entity => {
- var dto = entity.Adapt();
- dto.DateTime = entity.DateTime.ToRemoteDateTime(hoursOffset);
- return dto;
- });
+ var cacheItem = new CyclycArray(capacity);
+ cacheItem.AddRange(dtos);
- return dtos;
+ var item = new TelemetryDataCacheItem
+ {
+ FirstByDate = first,
+ LastData = cacheItem,
+ };
+ return item;
}
}
}
diff --git a/AsbCloudInfrastructure/Services/SAUB/TelemetryService.cs b/AsbCloudInfrastructure/Services/SAUB/TelemetryService.cs
index 593bf981..1f841aad 100644
--- a/AsbCloudInfrastructure/Services/SAUB/TelemetryService.cs
+++ b/AsbCloudInfrastructure/Services/SAUB/TelemetryService.cs
@@ -19,21 +19,20 @@ namespace AsbCloudInfrastructure.Services.SAUB
{
private readonly IAsbCloudDbContext db;
private readonly IMemoryCache memoryCache;
- private readonly ITelemetryTracker telemetryTracker;
+ private readonly TelemetryDataCache dataSaubCache;
private readonly ITimezoneService timezoneService;
public ITimezoneService TimeZoneService => timezoneService;
- public ITelemetryTracker TelemetryTracker => telemetryTracker;
public TelemetryService(
IAsbCloudDbContext db,
IMemoryCache memoryCache,
- ITelemetryTracker telemetryTracker,
+ TelemetryDataCache dataSaubCache,
ITimezoneService timezoneService)
{
this.db = db;
this.memoryCache = memoryCache;
- this.telemetryTracker = telemetryTracker;
+ this.dataSaubCache = dataSaubCache;
this.timezoneService = timezoneService;
}
@@ -47,34 +46,11 @@ namespace AsbCloudInfrastructure.Services.SAUB
memoryCache.DropBasic();
}
- 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)
{
- var telemetry = GetTelemetryCache().FirstOrDefault(t => t.Id == idTelemetry);
- if (telemetry is null)
- throw new Exception($"Telemetry id:{idTelemetry} does not exist");
-
- 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;
+ var cacheDataRange = dataSaubCache.GetOrDefaultDataDateRange(idTelemetry)
+ ?? new ();
+ return cacheDataRange;
}
public int GetOrCreateTelemetryIdByUid(string uid)
diff --git a/AsbCloudInfrastructure/Services/SAUB/TelemetryTracker.cs b/AsbCloudInfrastructure/Services/SAUB/TelemetryTracker.cs
deleted file mode 100644
index e3469f1e..00000000
--- a/AsbCloudInfrastructure/Services/SAUB/TelemetryTracker.cs
+++ /dev/null
@@ -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!;
-
- ///
- /// Время последнего запроса (по времени сервера)
- ///
- public DateTimeOffset LastTimeServer { get; set; }
-
- ///
- /// Дата первых данных в БД
- ///
- public DateTimeOffset TelemetryDateUtcMin { get; set; }
-
- ///
- /// Дата последних данных в БД
- ///
- public DateTimeOffset TelemetryDateUtcMax { get; set; }
-
- }
-
- private readonly ConcurrentDictionary telemetriesStats;
-
- public TelemetryTracker(IConfiguration configuration, IMemoryCache memoryCache)
- {
- // TODO: make this background work
- var contextOptions = new DbContextOptionsBuilder()
- .UseNpgsql(configuration.GetConnectionString("DefaultConnection"))
- .Options;
- var db = new AsbCloudDbContext(contextOptions);
-
- var cacheTelemetry = memoryCache.GetOrCreateBasic(db.Set().Include(t=>t.Well));
- var keyValuePairs = new Dictionary(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(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 GetTransmittingTelemetriesUids() =>
- telemetriesStats.Keys;
- }
-
-}
diff --git a/AsbCloudInfrastructure/Services/WellInfoService.cs b/AsbCloudInfrastructure/Services/WellInfoService.cs
index f37cb2f6..d24b04a3 100644
--- a/AsbCloudInfrastructure/Services/WellInfoService.cs
+++ b/AsbCloudInfrastructure/Services/WellInfoService.cs
@@ -1,13 +1,14 @@
using AsbCloudApp.Data;
using AsbCloudApp.Data.ProcessMap;
+using AsbCloudApp.Data.SAUB;
using AsbCloudApp.Repositories;
using AsbCloudApp.Requests;
using AsbCloudApp.Services;
using AsbCloudApp.Services.Subsystems;
using AsbCloudDb.Model;
using AsbCloudInfrastructure.Background;
+using AsbCloudInfrastructure.Services.SAUB;
using Mapster;
-using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Collections.Generic;
@@ -46,7 +47,8 @@ namespace AsbCloudInfrastructure.Services
var operationsStatService = serviceProvider.GetRequiredService();
var processMapRepository = serviceProvider.GetRequiredService();
var subsystemOperationTimeService = serviceProvider.GetRequiredService();
-
+ var telemetryDataSaubCache = serviceProvider.GetRequiredService>();
+
var activeWells = await wellService.GetAsync(new() {IdState = 1}, token);
IEnumerable activeWellsIds = activeWells
@@ -56,21 +58,6 @@ namespace AsbCloudInfrastructure.Services
.Where(w => w.IdTelemetry != null)
.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 processMaps = await processMapRepository.GetProcessMapAsync(processMapRequests, token);
@@ -83,43 +70,53 @@ namespace AsbCloudInfrastructure.Services
});
var operationsStat = await operationsStatService.GetWellsStatAsync(activeWellsIds, token);
+
var subsystemStat = await subsystemOperationTimeService.GetStatByActiveWells(activeWellsIds, token);
WellMapInfo = activeWells.Select(well => {
var wellMapInfo = well.Adapt();
-
- 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 wellSubsystemStat = subsystemStat.FirstOrDefault(s => s.Well.Id == well.Id);
+ double? currentDepth = null;
+ double? planTotalDepth = null;
+ DateTime lastTelemetryDate = default;
- double currentDepth = wellLastTelemetryInfo?.WellDepth
- ?? wellLastFactSection?.Fact?.WellDepthEnd
- ?? 0d;
+ if (well.IdTelemetry.HasValue)
+ {
+ 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
.Where(p => p.IdWell == well.Id)
.OrderBy(p => p.DepthEnd);
int? idSection = wellLastFactSection?.Id;
+ ProcessMapPlanDto? welllProcessMap = null;
- ProcessMapPlanDto? welllProcessMap;
- if (idSection is not null)
+ if (idSection.HasValue)
{
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;
}
- 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()
{
- Plan = wellDepthByProcessMap.FirstOrDefault(p => p.Id == well.Id)?.DepthEnd,
+ Plan = planTotalDepth,
Fact = currentDepth,
};
@@ -135,6 +132,7 @@ namespace AsbCloudInfrastructure.Services
Fact = wellOperationsStat?.Total.Fact?.RouteSpeed,
};
+ var wellSubsystemStat = subsystemStat.FirstOrDefault(s => s.Well.Id == well.Id);
wellMapInfo.SaubUsage = wellSubsystemStat?.SubsystemAKB?.KUsage ?? 0d;
wellMapInfo.SpinUsage = wellSubsystemStat?.SubsystemSpinMaster?.KUsage ?? 0d;
wellMapInfo.TvdLagPercent = wellOperationsStat?.TvdLagDays ?? 0d;
diff --git a/AsbCloudInfrastructure/Services/WellOperationService/OperationsStatService.cs b/AsbCloudInfrastructure/Services/WellOperationService/OperationsStatService.cs
index 408c895c..c32956d8 100644
--- a/AsbCloudInfrastructure/Services/WellOperationService/OperationsStatService.cs
+++ b/AsbCloudInfrastructure/Services/WellOperationService/OperationsStatService.cs
@@ -151,7 +151,7 @@ namespace AsbCloudInfrastructure.Services.WellOperationService
WellType = wellType?.Caption ?? "",
IdState = 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)
};
diff --git a/AsbCloudInfrastructure/Services/WellService.cs b/AsbCloudInfrastructure/Services/WellService.cs
index 2d2599b8..711b495e 100644
--- a/AsbCloudInfrastructure/Services/WellService.cs
+++ b/AsbCloudInfrastructure/Services/WellService.cs
@@ -57,15 +57,15 @@ namespace AsbCloudInfrastructure.Services
private void DropCacheRelationCompanyWell()
=> memoryCache.DropBasic();
- public DateTimeOffset GetLastTelemetryDate(int idWell)
+ public DateTime GetLastTelemetryDate(int idWell)
{
var well = GetOrDefault(idWell);
if (well?.IdTelemetry is null)
- return DateTimeOffset.MinValue;
+ return DateTime.MinValue;
- var lastTelemetryDate = telemetryService.GetLastTelemetryDate((int)well.IdTelemetry);
- return lastTelemetryDate;
+ var datesRange = telemetryService.GetDatesRange(well.IdTelemetry.Value);
+ return datesRange.To;
}
///
@@ -97,7 +97,7 @@ namespace AsbCloudInfrastructure.Services
dto.Latitude ??= gCluster.Key.Latitude ?? gDeposit.Key.Latitude;
dto.Longitude ??= gCluster.Key.Longitude ?? gDeposit.Key.Longitude;
if (well.IdTelemetry is not null)
- dto.LastTelemetryDate = telemetryService.GetLastTelemetryDate(well.IdTelemetry.Value);
+ dto.LastTelemetryDate = telemetryService.GetDatesRange(well.IdTelemetry.Value).To;
return dto;
}),
@@ -256,7 +256,7 @@ namespace AsbCloudInfrastructure.Services
dto.Cluster = entity.Cluster.Caption;
dto.Deposit = entity.Cluster.Deposit.Caption;
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
.Select(r => Convert(r.Company))
.ToList();
diff --git a/AsbCloudInfrastructure/Startup.cs b/AsbCloudInfrastructure/Startup.cs
index eec7d716..207270c2 100644
--- a/AsbCloudInfrastructure/Startup.cs
+++ b/AsbCloudInfrastructure/Startup.cs
@@ -10,6 +10,8 @@ using System;
using System.Threading.Tasks;
using System.Threading;
using AsbCloudInfrastructure.Background;
+using AsbCloudApp.Data.SAUB;
+using AsbCloudInfrastructure.Services.SAUB;
namespace AsbCloudInfrastructure
{
@@ -28,6 +30,9 @@ namespace AsbCloudInfrastructure
var wellService = provider.GetRequiredService();
wellService.EnshureTimezonesIsSetAsync(CancellationToken.None).Wait();// TODO: make this background work
+ _ = provider.GetRequiredService>();
+ _ = provider.GetRequiredService>();
+
var backgroundWorker = provider.GetRequiredService();
backgroundWorker.Push(WellInfoService.MakeWork());
backgroundWorker.Push(OperationDetectionWorkFactory.MakeWork());
@@ -45,7 +50,7 @@ namespace AsbCloudInfrastructure
var workAction = (string _, IServiceProvider _, CancellationToken _) => {
var bytes = GC.GetTotalMemory(false);
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;
};
var workPeriod = TimeSpan.FromMinutes(1);