DD.WellWorkover.Cloud/AsbCloudInfrastructure/Background/PeriodicWorks/WorkSubsystemOperationTimeCalcAbstract.cs

103 lines
3.9 KiB
C#

using AsbCloudApp.Data.SAUB;
using AsbCloudApp.Repositories;
using AsbCloudDb.Model;
using AsbCloudDb.Model.Subsystems;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
namespace AsbCloudInfrastructure.Background.PeriodicWorks;
public abstract class WorkSubsystemOperationTimeCalcAbstract : Work
{
protected const int idSubsystemTorqueMaster = 65537;
protected const int idSubsystemSpinMaster = 65536;
protected const int idSubsystemAPDRotor = 11;
protected const int idSubsystemAPDSlide = 12;
protected const int idSubsystemMse = 2;
private static TimeSpan obsoleteTime = TimeSpan.FromDays(365 * 100);
public WorkSubsystemOperationTimeCalcAbstract(string workId)
: base(workId)
{
Timeout = TimeSpan.FromMinutes(30);
}
protected override async Task Action(string id, IServiceProvider services, Action<string, double?> onProgressCallback, CancellationToken token)
{
var db = services.GetRequiredService<IAsbCloudDbContext>();
db.Database.SetCommandTimeout(TimeSpan.FromMinutes(5));
var telemetryLastDetectedDates = await GetTelemetryLastDetectedDates(services, db, token);
var count = telemetryLastDetectedDates.Count();
var i = 0d;
foreach (var item in telemetryLastDetectedDates)
{
onProgressCallback($"Start handling telemetry: {item.IdTelemetry} from {item.DateDetectedLast}", i++ / count);
var newOperationsSaub = await OperationTimeAsync(item.IdTelemetry, item.DateDetectedLast, db, token);
if (newOperationsSaub.Any())
{
db.SubsystemOperationTimes.AddRange(newOperationsSaub);
await db.SaveChangesAsync(token);
}
}
obsoleteTime = TimeSpan.FromDays(3);
}
protected abstract Task<IEnumerable<SubsystemOperationTime>> OperationTimeAsync(int idTelemetry, DateTimeOffset geDate, IAsbCloudDbContext db, CancellationToken token);
private static async Task<IEnumerable<TelemetryDateLast>> GetTelemetryLastDetectedDates(IServiceProvider services, IAsbCloudDbContext db, CancellationToken token)
{
var telemetryDataCache = services.GetRequiredService<ITelemetryDataCache<TelemetryDataSaubDto>>();
var updatingTelemetries = telemetryDataCache.GetStat()
.Where(tstat => (DateTimeOffset.Now - tstat.DateLast) < obsoleteTime);
var telemetryIds = updatingTelemetries
.Select(t => t.IdTelemetry)
.ToArray();
IEnumerable<TelemetryDateLast> lastDetectedDates = await GetLastSubsystemOperationTimeAsync(db, token);
lastDetectedDates = lastDetectedDates
.Where(s => telemetryIds.Contains(s.IdTelemetry));
var result = updatingTelemetries.Select(tstat => new TelemetryDateLast
{
IdTelemetry = tstat.IdTelemetry,
DateDetectedLast = lastDetectedDates.FirstOrDefault(ldd => ldd.IdTelemetry == tstat.IdTelemetry)?.DateDetectedLast
?? DateTimeOffset.UnixEpoch,
DateTelemetryLast = tstat.DateLast
});
return result;
}
private static async Task<IEnumerable<TelemetryDateLast>> GetLastSubsystemOperationTimeAsync(IAsbCloudDbContext db, CancellationToken token)
{
var result = await db.SubsystemOperationTimes
.GroupBy(o => o.IdTelemetry)
.Select(g => new TelemetryDateLast
{
IdTelemetry = g.Key,
DateDetectedLast = g.Max(o => o.DateEnd)
})
.ToArrayAsync(token);
return result;
}
protected class TelemetryDateLast
{
public int IdTelemetry { get; set; }
public DateTimeOffset DateDetectedLast { get; set; }
public DateTimeOffset DateTelemetryLast { get; internal set; }
}
}