From 17216acb80a7f3131511a2b4d54f61139a539c56 Mon Sep 17 00:00:00 2001 From: Frolov-Nikita Date: Tue, 31 Oct 2023 19:01:51 +0500 Subject: [PATCH] =?UTF-8?q?TelemetryDataBaseService.GetRangeAsync=20=D0=B0?= =?UTF-8?q?=D0=BE=D1=81=D1=81=D1=82=D0=B0=D0=BD=D0=BE=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=20=D0=B4=D0=BB=D1=8F=20Witsml.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Repositories/ITelemetryDataCache.cs | 7 ++ AsbCloudApp/Services/ITelemetryDataService.cs | 16 +++-- .../Services/SAUB/TelemetryDataBaseService.cs | 67 ++++++++++++++----- .../Services/SAUB/TelemetryDataCache.cs | 14 ++++ .../SAUB/TelemetryDataBaseController.cs | 10 +-- .../SubsystemOperationTimeController.cs | 2 +- 6 files changed, 89 insertions(+), 27 deletions(-) diff --git a/AsbCloudApp/Repositories/ITelemetryDataCache.cs b/AsbCloudApp/Repositories/ITelemetryDataCache.cs index 0bc73275..78f7008b 100644 --- a/AsbCloudApp/Repositories/ITelemetryDataCache.cs +++ b/AsbCloudApp/Repositories/ITelemetryDataCache.cs @@ -43,6 +43,13 @@ namespace AsbCloudApp.Repositories /// IEnumerable? GetOrDefault(int idTelemetry, TelemetryDataRequest request); + /// + /// Диапазон дат находящийся в кеше + /// + /// + /// + DatesRangeDto? GetOrDefaultCachedaDateRange(int idTelemetry); + /// /// Получить диапазон дат телеметрии. /// Дата первой записи телеметрии храниться отдельно и запоняется при инициализации diff --git a/AsbCloudApp/Services/ITelemetryDataService.cs b/AsbCloudApp/Services/ITelemetryDataService.cs index 154986b4..583da43e 100644 --- a/AsbCloudApp/Services/ITelemetryDataService.cs +++ b/AsbCloudApp/Services/ITelemetryDataService.cs @@ -37,13 +37,21 @@ namespace AsbCloudApp.Services Task> GetAsync(int idWell, TelemetryDataRequest request, CancellationToken token); /// - /// Получение периода за период + /// Период за который есть данные по скважине в рамках временного интервала /// /// - /// - /// + /// + /// + /// /// - DatesRangeDto? GetRange(int idWell, DateTimeOffset start, DateTimeOffset end); + Task GetRangeAsync(int idWell, DateTimeOffset geDate, DateTimeOffset? leDate, CancellationToken token); + + /// + /// Период за который есть данные по скважине + /// + /// + /// + DatesRangeDto? GetRange(int idWell); /// /// добавить/изменить данные тех. процесса (используется панелью) diff --git a/AsbCloudInfrastructure/Services/SAUB/TelemetryDataBaseService.cs b/AsbCloudInfrastructure/Services/SAUB/TelemetryDataBaseService.cs index 649f03de..a837ae04 100644 --- a/AsbCloudInfrastructure/Services/SAUB/TelemetryDataBaseService.cs +++ b/AsbCloudInfrastructure/Services/SAUB/TelemetryDataBaseService.cs @@ -1,4 +1,5 @@ using AsbCloudApp.Data; +using AsbCloudApp.Exceptions; using AsbCloudApp.Repositories; using AsbCloudApp.Services; using AsbCloudDb; @@ -204,28 +205,60 @@ namespace AsbCloudInfrastructure.Services.SAUB } /// - public DatesRangeDto? GetRange(int idWell, DateTimeOffset start, DateTimeOffset end) + public async Task GetRangeAsync(int idWell, DateTimeOffset geDate, DateTimeOffset? leDate, CancellationToken token) + { + var telemetry = telemetryService.GetOrDefaultTelemetryByIdWell(idWell) + ?? throw new ArgumentInvalidException(nameof(idWell), $"По скважине id:{idWell} нет телеметрии"); + + if ((DateTimeOffset.UtcNow - geDate) < TimeSpan.FromHours(12)) + { + // пробуем обойтись кешем + var cechedRange = telemetryDataCache.GetOrDefaultCachedaDateRange(telemetry.Id); + if (cechedRange?.From <= geDate) + { + var datesRange = new DatesRangeDto + { + From = geDate.DateTime, + To = cechedRange.To + }; + if (leDate.HasValue && leDate > geDate) + datesRange.To = leDate.Value.Date; + return datesRange; + } + } + + var query = db.Set() + .Where(entity => entity.IdTelemetry == telemetry.Id) + .Where(entity => entity.DateTime >= geDate.ToUniversalTime()); + + if(leDate.HasValue) + query = query.Where(entity => entity.DateTime <= leDate.Value.ToUniversalTime()); + + var gquery = query + .GroupBy(entity => entity.IdTelemetry) + .Select(group => new + { + MinDate = group.Min(entity => entity.DateTime), + MaxDate = group.Max(entity => entity.DateTime), + }); + + var result = await gquery.FirstAsync(token); + + var range = new DatesRangeDto + { + From = result.MinDate.ToOffset(TimeSpan.FromHours(telemetry.TimeZone!.Hours)).DateTime, + To = result.MaxDate.ToOffset(TimeSpan.FromHours(telemetry.TimeZone!.Hours)).DateTime, + }; + return range; + } + + public DatesRangeDto? GetRange(int idWell) { var telemetry = telemetryService.GetOrDefaultTelemetryByIdWell(idWell); if (telemetry is null) return default; - var datesRange = telemetryDataCache.GetOrDefaultDataDateRange(telemetry.Id); - - if (datesRange is null) - return null; - - var from = datesRange.From > start.DateTime - ? datesRange.From : start.DateTime; - - var to = datesRange.To < end.DateTime - ? datesRange.To : end.DateTime; - - return new DatesRangeDto - { - From = from, - To = to, - }; + return telemetryDataCache.GetOrDefaultDataDateRange(telemetry.Id); } public abstract TDto Convert(TEntity src, double timezoneOffset); diff --git a/AsbCloudInfrastructure/Services/SAUB/TelemetryDataCache.cs b/AsbCloudInfrastructure/Services/SAUB/TelemetryDataCache.cs index 0946de01..eabfcf77 100644 --- a/AsbCloudInfrastructure/Services/SAUB/TelemetryDataCache.cs +++ b/AsbCloudInfrastructure/Services/SAUB/TelemetryDataCache.cs @@ -147,6 +147,20 @@ namespace AsbCloudInfrastructure.Services.SAUB return new DatesRangeDto { From = from.Value, To = to }; } + public DatesRangeDto? GetOrDefaultCachedaDateRange(int idTelemetry) + { + if (!caches.TryGetValue(idTelemetry, out TelemetryDataCacheItem? cacheItem)) + return null; + + if (cacheItem.LastData.Count < 2) + return null; + + var to = cacheItem.LastData[^1].DateTime; + var from = cacheItem.LastData[0].DateTime; + + return new DatesRangeDto { From = from, To = to }; + } + public (TDto First, TDto Last)? GetOrDefaultFirstLast(int idTelemetry) { if (!caches.TryGetValue(idTelemetry, out TelemetryDataCacheItem? cacheItem)) diff --git a/AsbCloudWebApi/Controllers/SAUB/TelemetryDataBaseController.cs b/AsbCloudWebApi/Controllers/SAUB/TelemetryDataBaseController.cs index 4649d91d..21efdcde 100644 --- a/AsbCloudWebApi/Controllers/SAUB/TelemetryDataBaseController.cs +++ b/AsbCloudWebApi/Controllers/SAUB/TelemetryDataBaseController.cs @@ -131,15 +131,15 @@ namespace AsbCloudWebApi.Controllers.SAUB /// Возвращает диапазон дат за которые есть телеметрия за период времени /// /// - /// - /// + /// + /// /// /// [HttpGet("{idWell}/dateRange")] public virtual async Task> GetRangeAsync( [FromRoute] int idWell, - [Required] DateTimeOffset start, - [Required] DateTimeOffset end, + [Required] DateTimeOffset geDate, + DateTimeOffset? leDate, CancellationToken token) { int? idCompany = User.GetCompanyId(); @@ -153,7 +153,7 @@ namespace AsbCloudWebApi.Controllers.SAUB if (!isCompanyOwnsWell) return Forbid(); - var content = telemetryDataService.GetRange(idWell, start, end); + var content = await telemetryDataService.GetRangeAsync(idWell, geDate, leDate, token); return Ok(content); } diff --git a/AsbCloudWebApi/Controllers/Subsystems/SubsystemOperationTimeController.cs b/AsbCloudWebApi/Controllers/Subsystems/SubsystemOperationTimeController.cs index 0cf8250a..d5bf4aae 100644 --- a/AsbCloudWebApi/Controllers/Subsystems/SubsystemOperationTimeController.cs +++ b/AsbCloudWebApi/Controllers/Subsystems/SubsystemOperationTimeController.cs @@ -68,7 +68,7 @@ namespace AsbCloudWebApi.Controllers.Subsystems if (!await UserHasAccesToWellAsync(idWell, token)) return Forbid(); - var dateRange = telemetryDataSaubService.GetRange(idWell, DateTimeOffset.MinValue, DateTimeOffset.MaxValue); + var dateRange = telemetryDataSaubService.GetRange(idWell); return Ok(dateRange); }