DD.WellWorkover.Cloud/AsbCloudInfrastructure/Services/SAUB/TelemetryTracker.cs

157 lines
5.7 KiB
C#
Raw Normal View History

2022-04-11 18:00:34 +05:00
using AsbCloudApp.Data;
using AsbCloudApp.Services;
using AsbCloudDb.Model;
using Microsoft.EntityFrameworkCore;
2022-11-18 15:07:27 +05:00
using Microsoft.Extensions.Caching.Memory;
2022-04-11 18:00:34 +05:00
using Microsoft.Extensions.Configuration;
using System;
using System.Collections.Concurrent;
2022-04-11 18:00:34 +05:00
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
2022-04-11 18:00:34 +05:00
namespace AsbCloudInfrastructure.Services.SAUB
{
public class TelemetryTracker : ITelemetryTracker
{
class TrackerStat
{
//public int Id { get; set; }
2023-04-13 15:34:16 +05:00
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;
2022-11-18 15:07:27 +05:00
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);
2021-10-27 17:48:19 +05:00
var cacheTelemetry = memoryCache.GetOrCreateBasic(db.Set<Telemetry>().Include(t=>t.Well));
var keyValuePairs = new Dictionary<string, TrackerStat>(cacheTelemetry.Count());
foreach (var telemetry in cacheTelemetry)
{
2021-11-22 11:30:08 +05:00
var date = telemetry.Info?.DrillingStartDate
2022-04-15 13:36:09 +05:00
?? ParseDateFromUidOrDefault(telemetry.RemoteUid, DateTimeOffset.MinValue);
2021-11-22 11:30:08 +05:00
keyValuePairs[telemetry.RemoteUid] = new TrackerStat
{
RemoteUid = telemetry.RemoteUid,
TelemetryDateUtcMin = date,
TelemetryDateUtcMax = date,
LastTimeServer = date,
};
}
telemetriesStats = new ConcurrentDictionary<string, TrackerStat>(keyValuePairs);
2021-11-22 11:30:08 +05:00
Task.Run(async () =>
{
db.Database.SetCommandTimeout(2 * 60);
var dates = await db.TelemetryDataSaub
.GroupBy(d => d.IdTelemetry)
.Select(g => new
{
IdTelemetry = g.Key,
2022-04-01 17:55:44 +05:00
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,
2021-11-22 11:30:08 +05:00
t.DateMax,
t.DateMin,
}).Where(s => !string.IsNullOrEmpty(s.Uid));
foreach (var oldReq in oldRequests)
{
2023-04-13 15:34:16 +05:00
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;
});
}
2022-04-15 13:36:09 +05:00
private static DateTimeOffset ParseDateFromUidOrDefault(string remoteUid, DateTimeOffset defaultValue = default)
{
//example: uid = 20211102_173407926
2022-04-11 18:00:34 +05:00
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)
{
2022-04-11 18:00:34 +05:00
var stat = telemetriesStats.GetOrAdd(uid, _ => new TrackerStat
{
RemoteUid = uid,
TelemetryDateUtcMin = remoteDate
}
);
2022-04-11 18:00:34 +05:00
stat.LastTimeServer = DateTime.Now;
2021-12-22 12:34:59 +05:00
2022-04-11 18:00:34 +05:00
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;
}
}