diff --git a/AsbCloudApp/Services/IReportService.cs b/AsbCloudApp/Services/IReportService.cs
index 1f4a7d35..e5e24648 100644
--- a/AsbCloudApp/Services/IReportService.cs
+++ b/AsbCloudApp/Services/IReportService.cs
@@ -6,6 +6,7 @@ using System.Threading.Tasks;
namespace AsbCloudApp.Services
{
+#nullable enable
///
/// Сервис рапортов
///
@@ -57,5 +58,7 @@ namespace AsbCloudApp.Services
///
///
Task> GetAllReportsByWellAsync(int idWell, CancellationToken token);
+
+#nullable disable
}
}
diff --git a/AsbCloudInfrastructure/Background/BackgroundWorkerService.cs b/AsbCloudInfrastructure/Background/BackgroundWorker.cs
similarity index 89%
rename from AsbCloudInfrastructure/Background/BackgroundWorkerService.cs
rename to AsbCloudInfrastructure/Background/BackgroundWorker.cs
index e823284d..531d775e 100644
--- a/AsbCloudInfrastructure/Background/BackgroundWorkerService.cs
+++ b/AsbCloudInfrastructure/Background/BackgroundWorker.cs
@@ -1,4 +1,7 @@
-using Microsoft.Extensions.DependencyInjection;
+using AsbCloudInfrastructure.Services.DetectOperations;
+using AsbCloudInfrastructure.Services.Subsystems;
+using AsbCloudInfrastructure.Services;
+using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using System;
using System.Diagnostics;
@@ -18,13 +21,10 @@ namespace AsbCloudInfrastructure.Background
private static readonly TimeSpan exceptionHandleTimeout = TimeSpan.FromSeconds(2);
private readonly IServiceProvider serviceProvider;
private readonly WorkQueue workQueue = new WorkQueue();
-
+ public string? CurrentWorkId;
public BackgroundWorker(IServiceProvider serviceProvider)
{
this.serviceProvider = serviceProvider;
-#warning move StartAsync(CancellationToken.None).Wait() to THE factory
- Task.Delay(1_000)
- .ContinueWith(_=> StartAsync(CancellationToken.None).Wait());
}
///
@@ -69,11 +69,12 @@ namespace AsbCloudInfrastructure.Background
await Task.Delay(executePeriod, token);
continue;
}
-
+ CurrentWorkId = work.Id;
using var scope = serviceProvider.CreateScope();
try
{
+ Trace.TraceInformation($"Backgroud work:\"{work.Id}\" start.");
var task = work.ActionAsync(work.Id, scope.ServiceProvider, token);
await task.WaitAsync(work.Timeout, token);
@@ -90,8 +91,8 @@ namespace AsbCloudInfrastructure.Background
token);
await task.WaitAsync(exceptionHandleTimeout, token);
}
- }
-
+ }
+ CurrentWorkId = null;
await Task.Delay(minDelay, token);
}
}
diff --git a/AsbCloudInfrastructure/DependencyInjection.cs b/AsbCloudInfrastructure/DependencyInjection.cs
index a66ebe9e..35b956e2 100644
--- a/AsbCloudInfrastructure/DependencyInjection.cs
+++ b/AsbCloudInfrastructure/DependencyInjection.cs
@@ -98,9 +98,6 @@ namespace AsbCloudInfrastructure
services.AddScoped(provider => provider.GetService());
services.AddScoped();
- services.AddHostedService();
- services.AddHostedService();
- services.AddHostedService();
services.AddSingleton(new WitsInfoService());
services.AddSingleton(new InstantDataRepository());
services.AddSingleton(provider=> TelemetryDataCache.GetInstance(configuration));
diff --git a/AsbCloudInfrastructure/Services/DetectOperations/DetectedOperationService.cs b/AsbCloudInfrastructure/Services/DetectOperations/DetectedOperationService.cs
index 87decac8..7cca4f97 100644
--- a/AsbCloudInfrastructure/Services/DetectOperations/DetectedOperationService.cs
+++ b/AsbCloudInfrastructure/Services/DetectOperations/DetectedOperationService.cs
@@ -268,7 +268,7 @@ namespace AsbCloudInfrastructure.Services.DetectOperations
return query;
}
- private DetectedOperationDto Convert(DetectedOperation operation, WellDto well, IEnumerable operationValues, IEnumerable schedules)
+ private static DetectedOperationDto Convert(DetectedOperation operation, WellDto well, IEnumerable operationValues, IEnumerable schedules)
{
var dto = operation.Adapt();
dto.IdWell = well.Id;
diff --git a/AsbCloudInfrastructure/Services/DetectOperations/OperationDetectionBackgroundService.cs b/AsbCloudInfrastructure/Services/DetectOperations/OperationDetectionWorkFactory.cs
similarity index 69%
rename from AsbCloudInfrastructure/Services/DetectOperations/OperationDetectionBackgroundService.cs
rename to AsbCloudInfrastructure/Services/DetectOperations/OperationDetectionWorkFactory.cs
index e4b7c450..8ff6ebb8 100644
--- a/AsbCloudInfrastructure/Services/DetectOperations/OperationDetectionBackgroundService.cs
+++ b/AsbCloudInfrastructure/Services/DetectOperations/OperationDetectionWorkFactory.cs
@@ -1,7 +1,5 @@
using AsbCloudDb.Model;
using Microsoft.EntityFrameworkCore;
-using Microsoft.Extensions.Configuration;
-using Microsoft.Extensions.Hosting;
using System;
using System.Collections.Generic;
using System.Diagnostics;
@@ -9,14 +7,16 @@ using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using AsbCloudInfrastructure.Services.DetectOperations.Detectors;
+using AsbCloudInfrastructure.Background;
+using Microsoft.Extensions.DependencyInjection;
namespace AsbCloudInfrastructure.Services.DetectOperations
{
#nullable enable
- public class OperationDetectionBackgroundService : BackgroundService
+ public static class OperationDetectionWorkFactory
{
- private readonly string connectionString;
- private readonly TimeSpan period = TimeSpan.FromHours(1);
+ private const string workId = "Operation detection";
+ private static readonly TimeSpan workPeriod = TimeSpan.FromMinutes(30);
private static readonly DetectorAbstract[] detectors = new DetectorAbstract[]
{
@@ -31,49 +31,18 @@ namespace AsbCloudInfrastructure.Services.DetectOperations
new DetectorTemplatingWhileDrilling(),
};
- public OperationDetectionBackgroundService(IConfiguration configuration)
- {
- connectionString = configuration.GetConnectionString("DefaultConnection");
+ public static WorkPeriodic MakeWork()
+ {
+ var workPeriodic = new WorkPeriodic(workId, WorkAction, workPeriod);
+ workPeriodic.Timeout = TimeSpan.FromMinutes(30);
+ return workPeriodic;
}
- protected override async Task ExecuteAsync(CancellationToken token = default)
+ // TODO: Разделить этот акшн на более мелкие части И использовать telemetryServiceData<..> вместо прямого обращения к БД.
+ private static async Task WorkAction(string _, IServiceProvider serviceProvider, CancellationToken token)
{
- var timeToStartAnalysis = DateTime.Now;
- var options = new DbContextOptionsBuilder()
- .UseNpgsql(connectionString)
- .Options;
+ using var db = serviceProvider.GetRequiredService();
- while (!token.IsCancellationRequested)
- {
- if (DateTime.Now > timeToStartAnalysis)
- {
- timeToStartAnalysis = DateTime.Now + period;
- try
- {
- using var context = new AsbCloudDbContext(options);
- var added = await DetectedAllTelemetriesAsync(context, token);
- Trace.TraceInformation($"Total detection complete. Added {added} operations.");
- }
- catch (Exception ex)
- {
- Trace.TraceError(ex.Message);
- }
- GC.Collect();
- }
-
- var ms = (int)(timeToStartAnalysis - DateTime.Now).TotalMilliseconds;
- ms = ms > 100 ? ms : 100;
- await Task.Delay(ms, token).ConfigureAwait(false);
- }
- }
-
- public override async Task StopAsync(CancellationToken token)
- {
- await base.StopAsync(token).ConfigureAwait(false);
- }
-
- private static async Task DetectedAllTelemetriesAsync(IAsbCloudDbContext db, CancellationToken token)
- {
var lastDetectedDates = await db.DetectedOperations
.GroupBy(o => o.IdTelemetry)
.Select(g => new
@@ -88,7 +57,7 @@ namespace AsbCloudInfrastructure.Services.DetectOperations
.Select(t => t.Id)
.ToListAsync(token);
- var JounedlastDetectedDates = telemetryIds
+ var joinedlastDetectedDates = telemetryIds
.GroupJoin(lastDetectedDates,
t => t,
o => o.IdTelemetry,
@@ -97,8 +66,9 @@ namespace AsbCloudInfrastructure.Services.DetectOperations
IdTelemetry = outer,
inner.SingleOrDefault()?.LastDate,
});
+
var affected = 0;
- foreach (var item in JounedlastDetectedDates)
+ foreach (var item in joinedlastDetectedDates)
{
var stopwatch = Stopwatch.StartNew();
var newOperations = await DetectOperationsAsync(item.IdTelemetry, item.LastDate ?? DateTimeOffset.MinValue, db, token);
@@ -109,7 +79,6 @@ namespace AsbCloudInfrastructure.Services.DetectOperations
affected += await db.SaveChangesAsync(token);
}
}
- return affected;
}
private static async Task> DetectOperationsAsync(int idTelemetry, DateTimeOffset begin, IAsbCloudDbContext db, CancellationToken token)
diff --git a/AsbCloudInfrastructure/Services/LimitingParameterBackgroundService.cs b/AsbCloudInfrastructure/Services/LimitingParameterBackgroundService.cs
index 261ceb9c..1420ea89 100644
--- a/AsbCloudInfrastructure/Services/LimitingParameterBackgroundService.cs
+++ b/AsbCloudInfrastructure/Services/LimitingParameterBackgroundService.cs
@@ -1,61 +1,37 @@
using AsbCloudDb.Model;
using Microsoft.EntityFrameworkCore;
-using Microsoft.Extensions.Configuration;
-using Microsoft.Extensions.Hosting;
using System;
using System.Data.Common;
using System.Data;
-using System.Diagnostics;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Collections.Generic;
+using AsbCloudInfrastructure.Background;
+using Microsoft.Extensions.DependencyInjection;
namespace AsbCloudInfrastructure.Services
{
#nullable enable
- internal class LimitingParameterBackgroundService : BackgroundService
+ internal static class LimitingParameterCalcWorkFactory
{
- private readonly string connectionString;
- private readonly TimeSpan period = TimeSpan.FromHours(1);
+ private const string workId = "Limiting parameter calc";
+ private static readonly TimeSpan workPeriod = TimeSpan.FromMinutes(30);
- public LimitingParameterBackgroundService(IConfiguration configuration)
+ public static WorkPeriodic MakeWork()
{
- connectionString = configuration.GetConnectionString("DefaultConnection");
- }
-
- protected override async Task ExecuteAsync(CancellationToken token)
- {
- var timeToStart = DateTime.Now;
- var options = new DbContextOptionsBuilder()
- .UseNpgsql(connectionString)
- .Options;
- while (!token.IsCancellationRequested)
+ var workPeriodic = new WorkPeriodic(workId, WorkAction, workPeriod)
{
- if (DateTime.Now > timeToStart)
- {
- timeToStart = DateTime.Now + period;
- try
- {
- using var context = new AsbCloudDbContext(options);
- var added = await LimitingParameterAsync(context, token);
- Trace.TraceInformation($"Total limiting parameter complete. Added {added} limiting parameters.");
- }
- catch (Exception ex)
- {
- Trace.TraceError(ex.Message);
- }
- GC.Collect();
- }
- var ms = (int)(timeToStart - DateTime.Now).TotalMilliseconds;
- ms = ms > 100 ? ms : 100;
- await Task.Delay(ms, token).ConfigureAwait(false);
- }
+ Timeout = TimeSpan.FromMinutes(30)
+ };
+ return workPeriodic;
}
- private static async Task LimitingParameterAsync(IAsbCloudDbContext context, CancellationToken token)
+ // TODO: Разделить этот акшн на более мелкие части И использовать telemetryServiceData<..> вместо прямого обращения к БД.
+ private static async Task WorkAction(string _, IServiceProvider serviceProvider, CancellationToken token)
{
- var lastDetectedDates = await context.LimitingParameter
+ using var db = serviceProvider.GetRequiredService();
+ var lastDetectedDates = await db.LimitingParameter
.GroupBy(o => o.IdTelemetry)
.Select(g => new
{
@@ -64,7 +40,7 @@ namespace AsbCloudInfrastructure.Services
})
.ToListAsync(token);
- var telemetryIds = await context.Telemetries
+ var telemetryIds = await db.Telemetries
.Where(t => t.Info != null && t.TimeZone != null)
.Select(t => t.Id)
.ToListAsync(token);
@@ -79,17 +55,15 @@ namespace AsbCloudInfrastructure.Services
inner.SingleOrDefault()?.LastDate,
});
- var affected = 0;
foreach (var item in telemetryLastDetectedDates)
{
- var newLimitingParameters = await GetLimitingParameterAsync(item.IdTelemetry, item.LastDate ?? DateTimeOffset.MinValue, context, token);
+ var newLimitingParameters = await GetLimitingParameterAsync(item.IdTelemetry, item.LastDate ?? DateTimeOffset.MinValue, db, token);
if (newLimitingParameters?.Any() == true)
{
- context.LimitingParameter.AddRange(newLimitingParameters);
- affected += await context.SaveChangesAsync(token);
+ db.LimitingParameter.AddRange(newLimitingParameters);
+ await db.SaveChangesAsync(token);
}
}
- return affected;
}
private static async Task> GetLimitingParameterAsync(int idTelemetry, DateTimeOffset begin, IAsbCloudDbContext db, CancellationToken token)
diff --git a/AsbCloudInfrastructure/Services/SAUB/TelemetryTracker.cs b/AsbCloudInfrastructure/Services/SAUB/TelemetryTracker.cs
index 190094a1..d3f80a9b 100644
--- a/AsbCloudInfrastructure/Services/SAUB/TelemetryTracker.cs
+++ b/AsbCloudInfrastructure/Services/SAUB/TelemetryTracker.cs
@@ -41,6 +41,7 @@ namespace AsbCloudInfrastructure.Services.SAUB
public TelemetryTracker(IConfiguration configuration, IMemoryCache memoryCache)
{
+ // TODO: make this background work
var contextOptions = new DbContextOptionsBuilder()
.UseNpgsql(configuration.GetConnectionString("DefaultConnection"))
.Options;
diff --git a/AsbCloudInfrastructure/Services/Subsystems/SubsystemOperationTimeBackgroundService.cs b/AsbCloudInfrastructure/Services/Subsystems/SubsystemOperationTimeCalcWorkFactory.cs
similarity index 86%
rename from AsbCloudInfrastructure/Services/Subsystems/SubsystemOperationTimeBackgroundService.cs
rename to AsbCloudInfrastructure/Services/Subsystems/SubsystemOperationTimeCalcWorkFactory.cs
index 7f241ca3..9efc29a8 100644
--- a/AsbCloudInfrastructure/Services/Subsystems/SubsystemOperationTimeBackgroundService.cs
+++ b/AsbCloudInfrastructure/Services/Subsystems/SubsystemOperationTimeCalcWorkFactory.cs
@@ -1,9 +1,9 @@
using AsbCloudDb.Model;
using AsbCloudDb.Model.Subsystems;
+using AsbCloudInfrastructure.Background;
using AsbCloudInfrastructure.Services.Subsystems.Utils;
using Microsoft.EntityFrameworkCore;
-using Microsoft.Extensions.Configuration;
-using Microsoft.Extensions.Hosting;
+using Microsoft.Extensions.DependencyInjection;
using System;
using System.Collections.Generic;
using System.Data;
@@ -16,56 +16,30 @@ using System.Threading.Tasks;
namespace AsbCloudInfrastructure.Services.Subsystems
{
#nullable enable
- internal class SubsystemOperationTimeBackgroundService : BackgroundService
+ internal static class SubsystemOperationTimeCalcWorkFactory
{
- private readonly string connectionString;
- private readonly TimeSpan period = TimeSpan.FromHours(1);
+ private const string workId = "Subsystem operation time calc";
+ private static readonly TimeSpan workPeriod = TimeSpan.FromMinutes(30);
+
private const int idSubsytemTorqueMaster = 65537;
private const int idSubsytemSpinMaster = 65536;
private const int idSubsytemAkb = 1;
private const int idSubsytemMse = 2;
- public SubsystemOperationTimeBackgroundService(IConfiguration configuration)
+ public static WorkPeriodic MakeWork()
{
- connectionString = configuration.GetConnectionString("DefaultConnection");
- }
-
- protected override async Task ExecuteAsync(CancellationToken token)
- {
- var timeToStart = DateTime.Now;
- var options = new DbContextOptionsBuilder()
- .UseNpgsql(connectionString)
- .Options;
- while (!token.IsCancellationRequested)
+ var workPeriodic = new WorkPeriodic(workId, WorkAction, workPeriod)
{
- if (DateTime.Now > timeToStart)
- {
- timeToStart = DateTime.Now + period;
- try
- {
- using var context = new AsbCloudDbContext(options);
- var added = await OperationTimeAllTelemetriesAsync(context, token);
- Trace.TraceInformation($"Total subsystem operation time complete. Added {added} operations time.");
- }
- catch (Exception ex)
- {
- Trace.TraceError(ex.Message);
- }
- GC.Collect();
- }
- var ms = (int)(timeToStart - DateTime.Now).TotalMilliseconds;
- ms = ms > 100 ? ms : 100;
- await Task.Delay(ms, token).ConfigureAwait(false);
- }
+ Timeout = TimeSpan.FromMinutes(30)
+ };
+ return workPeriodic;
}
- public override async Task StopAsync(CancellationToken token)
+ // TODO: Разделить этот акшн на более мелкие части И использовать telemetryServiceData<..> вместо прямого обращения к БД.
+ private static async Task WorkAction(string _, IServiceProvider serviceProvider, CancellationToken token)
{
- await base.StopAsync(token).ConfigureAwait(false);
- }
+ using var db = serviceProvider.GetRequiredService();
- private static async Task OperationTimeAllTelemetriesAsync(IAsbCloudDbContext db, CancellationToken token)
- {
var lastDetectedDates = await db.SubsystemOperationTimes
.GroupBy(o => o.IdTelemetry)
.Select(g => new
@@ -90,23 +64,21 @@ namespace AsbCloudInfrastructure.Services.Subsystems
inner.SingleOrDefault()?.LastDate,
});
- var affected = 0;
foreach (var item in telemetryLastDetectedDates)
{
var newOperationsSaub = await OperationTimeSaubAsync(item.IdTelemetry, item.LastDate ?? DateTimeOffset.MinValue, db, token);
if (newOperationsSaub?.Any() == true)
{
db.SubsystemOperationTimes.AddRange(newOperationsSaub);
- affected += await db.SaveChangesAsync(token);
+ await db.SaveChangesAsync(token);
}
var newOperationsSpin = await OperationTimeSpinAsync(item.IdTelemetry, item.LastDate ?? DateTimeOffset.MinValue, db, token);
if (newOperationsSpin?.Any() == true)
{
db.SubsystemOperationTimes.AddRange(newOperationsSpin);
- affected += await db.SaveChangesAsync(token);
+ await db.SaveChangesAsync(token);
}
}
- return affected;
}
private static async Task ExecuteReaderAsync(IAsbCloudDbContext db, string query, CancellationToken token)
diff --git a/AsbCloudInfrastructure/Startup.cs b/AsbCloudInfrastructure/Startup.cs
index c8dc24a9..01768371 100644
--- a/AsbCloudInfrastructure/Startup.cs
+++ b/AsbCloudInfrastructure/Startup.cs
@@ -1,9 +1,14 @@
using AsbCloudApp.Services;
using AsbCloudDb.Model;
+using AsbCloudInfrastructure.Services.DetectOperations;
+using AsbCloudInfrastructure.Services.Subsystems;
+using AsbCloudInfrastructure.Services;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using System;
+using System.Threading.Tasks;
+using System.Threading;
namespace AsbCloudInfrastructure
{
@@ -12,13 +17,22 @@ namespace AsbCloudInfrastructure
public static void BeforeRunHandler(IHost host)
{
using var scope = host.Services.CreateScope();
- var context = scope.ServiceProvider.GetService();
- context.Database.SetCommandTimeout(TimeSpan.FromSeconds(2 * 60));
+ var provider = scope.ServiceProvider;
+ var context = provider.GetService();
+ context.Database.SetCommandTimeout(TimeSpan.FromSeconds(2 * 60));
context.Database.Migrate();
- var wellService = scope.ServiceProvider.GetService();
- wellService.EnshureTimezonesIsSetAsync(System.Threading.CancellationToken.None).Wait();
+ var wellService = provider.GetRequiredService();
+ wellService.EnshureTimezonesIsSetAsync(CancellationToken.None).Wait();// TODO: make this background work
+
+ var backgroundWorker = provider.GetRequiredService();
+ backgroundWorker.Push(OperationDetectionWorkFactory.MakeWork());
+ backgroundWorker.Push(SubsystemOperationTimeCalcWorkFactory.MakeWork());
+ backgroundWorker.Push(LimitingParameterCalcWorkFactory.MakeWork());
+
+ Task.Delay(1_000)
+ .ContinueWith(async (_) => await backgroundWorker.StartAsync(CancellationToken.None));
}
}
}