From a7a82b902a218baf14f78824e4cbd8aa1c277d52 Mon Sep 17 00:00:00 2001 From: Mikhail Trubnikov Date: Mon, 22 Dec 2025 17:03:41 +1000 Subject: [PATCH] =?UTF-8?q?feat(distributor):=20=D0=BF=D0=B5=D1=80=D0=B2?= =?UTF-8?q?=D0=B0=D1=8F=20=D0=B2=D0=B5=D1=80=D1=81=D0=B8=D1=8F=20=D1=80?= =?UTF-8?q?=D0=B0=D1=81=D0=BF=D1=80=D0=B5=D0=B4=D0=B5=D0=BB=D0=B8=D1=82?= =?UTF-8?q?=D0=B5=D0=BB=D1=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- PARR.API.sln | 12 - PARR.DAL/NextRunServices/INextRunService.cs | 29 ++ .../Models/TemplateNextRunDto.cs | 12 + PARR.DAL/NextRunServices/NextRunService.cs | 79 +++++ .../Subservices/ITemplateDistributor.cs | 18 + .../Subservices/TemplateDistributor.cs | 322 ++++++++++++++++++ PARR.DAL/ParrDalInstaller.cs | 11 + .../Implementations/WeekendDayService.cs | 2 +- .../TemplateTaskGenerator.cs | 1 + docker-compose.dcproj | 1 - docker-compose.template-task-generator.yml | 27 -- 11 files changed, 473 insertions(+), 41 deletions(-) create mode 100644 PARR.DAL/NextRunServices/INextRunService.cs create mode 100644 PARR.DAL/NextRunServices/Models/TemplateNextRunDto.cs create mode 100644 PARR.DAL/NextRunServices/NextRunService.cs create mode 100644 PARR.DAL/NextRunServices/Subservices/ITemplateDistributor.cs create mode 100644 PARR.DAL/NextRunServices/Subservices/TemplateDistributor.cs delete mode 100644 docker-compose.template-task-generator.yml diff --git a/PARR.API.sln b/PARR.API.sln index 393cb427..3f066499 100644 --- a/PARR.API.sln +++ b/PARR.API.sln @@ -92,10 +92,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PARR.AIHITRelationshipsSync EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PARR.TemplateGeneratorWorker", "PARR.TemplateGeneratorWorker\PARR.TemplateGeneratorWorker.csproj", "{17245D0B-3290-4C96-B5B1-4B0711BABAF2}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PARR.TemplateTaskGenerator", "PARR.TemplateTaskGenerator\PARR.TemplateTaskGenerator.csproj", "{D4C51090-CE06-4158-9A0E-961744872411}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PARR.TemplateTaskGeneratorWorker", "PARR.TemplateTaskGeneratorWorker\PARR.TemplateTaskGeneratorWorker.csproj", "{93249642-DF7D-41A1-87C0-6E3BAECB43EC}" -EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PARR.TemplateMatcher", "PARR.TemplateMatcher\PARR.TemplateMatcher.csproj", "{EADC9A11-426A-41E9-98B4-010295412FF5}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PARR.TemplateMatcherWorker", "PARR.TemplateMatcherWorker\PARR.TemplateMatcherWorker.csproj", "{DA6B2A17-6E64-4E2C-8D4C-E278BEE94E03}" @@ -272,14 +268,6 @@ Global {17245D0B-3290-4C96-B5B1-4B0711BABAF2}.Debug|Any CPU.Build.0 = Debug|Any CPU {17245D0B-3290-4C96-B5B1-4B0711BABAF2}.Release|Any CPU.ActiveCfg = Release|Any CPU {17245D0B-3290-4C96-B5B1-4B0711BABAF2}.Release|Any CPU.Build.0 = Release|Any CPU - {D4C51090-CE06-4158-9A0E-961744872411}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {D4C51090-CE06-4158-9A0E-961744872411}.Debug|Any CPU.Build.0 = Debug|Any CPU - {D4C51090-CE06-4158-9A0E-961744872411}.Release|Any CPU.ActiveCfg = Release|Any CPU - {D4C51090-CE06-4158-9A0E-961744872411}.Release|Any CPU.Build.0 = Release|Any CPU - {93249642-DF7D-41A1-87C0-6E3BAECB43EC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {93249642-DF7D-41A1-87C0-6E3BAECB43EC}.Debug|Any CPU.Build.0 = Debug|Any CPU - {93249642-DF7D-41A1-87C0-6E3BAECB43EC}.Release|Any CPU.ActiveCfg = Release|Any CPU - {93249642-DF7D-41A1-87C0-6E3BAECB43EC}.Release|Any CPU.Build.0 = Release|Any CPU {EADC9A11-426A-41E9-98B4-010295412FF5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {EADC9A11-426A-41E9-98B4-010295412FF5}.Debug|Any CPU.Build.0 = Debug|Any CPU {EADC9A11-426A-41E9-98B4-010295412FF5}.Release|Any CPU.ActiveCfg = Release|Any CPU diff --git a/PARR.DAL/NextRunServices/INextRunService.cs b/PARR.DAL/NextRunServices/INextRunService.cs new file mode 100644 index 00000000..d62fd757 --- /dev/null +++ b/PARR.DAL/NextRunServices/INextRunService.cs @@ -0,0 +1,29 @@ +namespace PARR.DAL.NextRunServices +{ + public interface INextRunService + { + /// + /// Получить список TemplateId, NextRun по jobGroupId с автораспределением + /// + /// + /// + Task> GetNextRunForJobGroupWithAutoDistributionAsync(Guid jobGroupId); + + + /// + /// Получить NextRun по jobGroupId с расписанием ЕСПП + /// + /// + /// + Task GetNextRunForJobGroupWithEsppSchedulleAsync(Guid jobGroupId); + + + /// + /// Получить NextRun по id шаблона + /// + /// + /// + Task GetNextRunForTemplate(Guid templateId); + + } +} diff --git a/PARR.DAL/NextRunServices/Models/TemplateNextRunDto.cs b/PARR.DAL/NextRunServices/Models/TemplateNextRunDto.cs new file mode 100644 index 00000000..839fe5c6 --- /dev/null +++ b/PARR.DAL/NextRunServices/Models/TemplateNextRunDto.cs @@ -0,0 +1,12 @@ +namespace PARR.DAL.NextRunServices.Models +{ + /// + /// Модель шаблона, для расчета NextRun + /// + public class TemplateNextRunDto + { + public Guid Id { get; set; } + + public DateTimeOffset? NextRun { get; set; } + } +} diff --git a/PARR.DAL/NextRunServices/NextRunService.cs b/PARR.DAL/NextRunServices/NextRunService.cs new file mode 100644 index 00000000..796e6599 --- /dev/null +++ b/PARR.DAL/NextRunServices/NextRunService.cs @@ -0,0 +1,79 @@ + +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Logging; +using PARR.DAL.Services.Interfaces; +using PARR.DAL.Services.Interfaces.Job; +using PARR.DAL.TransformServices; + +namespace PARR.DAL.NextRunServices +{ + internal class NextRunService : INextRunService + { + private readonly ILogger logger; + private readonly ITemplateService templateService; + private readonly IJobGroupService jobGroupService; + private readonly IEsppScheduleTransformService esppScheduleTransformService; + + public NextRunService( + ILogger logger, + ITemplateService templateService, + IJobGroupService jobGroupService, + IEsppScheduleTransformService esppScheduleTransformService + ) + { + this.logger = logger; + this.templateService = templateService; + this.jobGroupService = jobGroupService; + this.esppScheduleTransformService = esppScheduleTransformService; + } + + + public Task> GetNextRunForJobGroupWithAutoDistributionAsync(Guid jobGroupId) + { + //TODO: + throw new NotImplementedException(); + } + + + public async Task GetNextRunForJobGroupWithEsppSchedulleAsync(Guid jobGroupId) + { + var jobGroup = await jobGroupService.Get().AsNoTracking().FirstOrDefaultAsync(t => t.Id == jobGroupId); + + if (jobGroup == null) + { + logger.LogError("Не найдена группа работ с Id: {jobGroupId}.", jobGroupId); + throw new ArgumentNullException(nameof(jobGroupId), $"Не найдена группа работ с Id: {jobGroupId}"); + } + + // Берем из обычного расписания ЕСПП + return await esppScheduleTransformService.GetNextDateAsync(jobGroupId, jobGroup.ReferenceDate); + } + + + public async Task GetNextRunForTemplate(Guid templateId) + { + var template = await templateService.Get() + .Include(t => t.Job).ThenInclude(t => t.Group) + .AsNoTracking() + .FirstOrDefaultAsync(t => t.Id == templateId); + + if (template == null) + { + logger.LogError("Не найдена шаблон с Id: {templateId}.", templateId); + throw new ArgumentNullException(nameof(templateId), $"Не найдена шаблон с Id: {templateId}"); + } + + if (template.Job!.Group!.IsAutoDistributionEnabled == true) + { + // включено автораспределение + //TODO: !!!!!!!!!!!!!!!! добавить метод рассчета с учетом распределения + throw new NotImplementedException("добавить метод рассчета с учетом распределения"); + } + else + { + // считаем как ЕСПП + return await esppScheduleTransformService.GetNextDateAsync(template.Job.Group.Id, template.Job.Group.ReferenceDate); + } + } + } +} diff --git a/PARR.DAL/NextRunServices/Subservices/ITemplateDistributor.cs b/PARR.DAL/NextRunServices/Subservices/ITemplateDistributor.cs new file mode 100644 index 00000000..dd8cccd4 --- /dev/null +++ b/PARR.DAL/NextRunServices/Subservices/ITemplateDistributor.cs @@ -0,0 +1,18 @@ +using PARR.DAL.Models; +using PARR.DAL.NextRunServices.Models; + +namespace PARR.DAL.NextRunServices.Subservices +{ + internal interface ITemplateDistributor + { + Task> GetValidNextRunAsync(TemplateNextRunDto template, DateOnly startDate, DateOnly endDate, TimeSpan executionTime); + + Task> GetValidNextRunsAsync(List templates, DateOnly startDate, DateOnly endDate, TimeSpan executionTime); + + Task> ReassignOutdatedRunsAsync(List templates, DateOnly startDate, DateOnly endDate, TimeSpan executionTime); + + Task> RebalanceTemplatesAsync(List templates, DateOnly startDate, DateOnly endDate, TimeSpan executionTime); + + Task> ScheduleTemplatesAsync(List templates, DateOnly startDate, DateOnly endDate, TimeSpan executionTime); + } +} diff --git a/PARR.DAL/NextRunServices/Subservices/TemplateDistributor.cs b/PARR.DAL/NextRunServices/Subservices/TemplateDistributor.cs new file mode 100644 index 00000000..25bf5191 --- /dev/null +++ b/PARR.DAL/NextRunServices/Subservices/TemplateDistributor.cs @@ -0,0 +1,322 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Logging; +using PARR.DAL.NextRunServices.Models; +using PARR.DAL.Services.Interfaces; + +namespace PARR.DAL.NextRunServices.Subservices +{ + internal class TemplateDistributor : ITemplateDistributor + { + private readonly ILogger logger; + private readonly IWeekendDayService weekendDayService; + + public TemplateDistributor( + ILogger logger, + IWeekendDayService weekendDayService + ) + { + this.logger = logger; + this.weekendDayService = weekendDayService; + } + + /// + /// Распределяет шаблоны по рабочим дням в заданном диапазоне с равномерной загрузкой. + /// Возвращает список с Id и новой датой выполнения для каждого шаблона. + /// + public async Task> ScheduleTemplatesAsync(List templates, DateOnly startDate, DateOnly endDate, TimeSpan executionTime) + { + logger.LogInformation("Начинаем распределение {Count} шаблонов с {StartDate} по {EndDate}", templates.Count, startDate, endDate); + + // Получаем список выходных/праздничных дней в заданном диапазоне + var weekends = (await weekendDayService.GetWeekends(startDate, endDate).ToListAsync()).ToHashSet(); + + // Получаем список рабочих дней (исключая выходные и праздники) + var workDays = GetWorkDays(startDate, endDate, weekends); + + logger.LogDebug("Найдено {Count} рабочих дней", workDays.Count); + + // Проверяем, есть ли хотя бы один рабочий день + if (workDays.Count == 0) + { + logger.LogWarning("Нет доступных рабочих дней в диапазоне {StartDate} - {EndDate}", startDate, endDate); + return new List(); + } + + var totalWorks = templates.Count; // Общее количество шаблонов для распределения + var totalDays = workDays.Count; // Общее количество доступных рабочих дней + + // Сортируем шаблоны: сначала без даты (NextRun == null), затем с датой + var sortedTemplates = templates.OrderBy(t => t.NextRun.HasValue ? 1 : 0).ToList(); + + // Вычисляем интервал между работами: сколько "дней" приходится на одну работу + // Это позволяет равномерно распределить работы по всему периоду + // т е например 2 работы распределятся на 30 дней равномерно, не будут идти подряд + var interval = (double)totalDays / totalWorks; + + // Проходим по всем шаблонам и распределяем их равномерно по дням + for (int i = 0; i < totalWorks; i++) + { + // Вычисляем индекс дня, на который нужно назначить i-ю работу + // Используем округление, чтобы получить ближайший день + var dayIndex = (int)Math.Round(i * interval); + + // Защита от возможного выхода за границы массива из-за округления + if (dayIndex >= totalDays) dayIndex = totalDays - 1; + + // Получаем дату из списка рабочих дней по вычисленному индексу + var date = workDays[dayIndex]; + + // Формируем дату выполнения: дата + заданное время (executionTime) + var nextRun = new DateTimeOffset(date.Year, date.Month, date.Day, executionTime.Hours, executionTime.Minutes, executionTime.Seconds, TimeSpan.Zero); + + // Назначаем вычисленную дату выполнения шаблону + sortedTemplates[i].NextRun = nextRun; + + logger.LogDebug("Шаблон {TemplateId} назначен на {NextRun}", sortedTemplates[i].Id, nextRun); + } + + logger.LogInformation("Распределение завершено. Возвращаем {Count} записей.", templates.Count); + + // Возвращаем список шаблонов с обновлёнными датами выполнения + return templates.Select(t => new TemplateNextRunDto { Id = t.Id, NextRun = t.NextRun!.Value }).ToList(); + } + + + /// + /// Обновляет устаревшие даты выполнения шаблонов. + /// Возвращает список шаблонов, чьи даты были изменены. + /// + public async Task> ReassignOutdatedRunsAsync(List templates, DateOnly startDate, DateOnly endDate, TimeSpan executionTime) + { + logger.LogInformation("Начинаем переназначение устаревших дат выполнения"); + + // Получаем список выходных/праздничных дней + var weekends = (await weekendDayService.GetWeekends(startDate, endDate).ToListAsync()).ToHashSet(); + var workDays = GetWorkDays(startDate, endDate, weekends).OrderBy(d => d).ToList(); + + var now = DateTimeOffset.UtcNow; + var result = new List(); + + foreach (var template in templates) + { + if (template.NextRun.HasValue && template.NextRun.Value < now) + { + logger.LogDebug("Шаблон {TemplateId} с датой {OldDate} устарел", template.Id, template.NextRun); + + var newDate = FindNextAvailableDate(workDays, DateOnly.FromDateTime(now.DateTime), DateOnly.FromDateTime(template.NextRun.Value.Date)); + if (newDate.HasValue) + { + var nextRun = new DateTimeOffset(newDate.Value.Year, newDate.Value.Month, newDate.Value.Day, executionTime.Hours, executionTime.Minutes, executionTime.Seconds, TimeSpan.Zero); + template.NextRun = nextRun; + + logger.LogDebug("Шаблон {TemplateId} перенесен на {NewDate}", template.Id, nextRun); + + result.Add(new TemplateNextRunDto { Id = template.Id, NextRun = nextRun }); + } + else + { + logger.LogWarning("Не удалось найти новую дату для шаблона {TemplateId}", template.Id); + } + } + } + + logger.LogInformation("Переназначение завершено. Изменено {Count} записей.", result.Count); + + return result; + } + + + /// + /// Перераспределяет только те шаблоны, у которых дата недействительна (выходной, вне периода). + /// Возвращает список всех шаблонов с новыми или старыми датами. + /// + public async Task> RebalanceTemplatesAsync(List templates, DateOnly startDate, DateOnly endDate, TimeSpan executionTime) + { + logger.LogInformation("Начинаем перераспределение шаблонов"); + + // Получаем список выходных/праздничных дней + var weekends = (await weekendDayService.GetWeekends(startDate, endDate).ToListAsync()).ToHashSet(); + + var workDays = GetWorkDays(startDate, endDate, weekends); + var validDates = new HashSet(workDays); + + // Отфильтруем шаблоны с недействительной датой + var unassigned = templates.Where(t => !t.NextRun.HasValue || !validDates.Contains(DateOnly.FromDateTime(t.NextRun.Value.Date))).ToList(); + + logger.LogDebug("Найдено {Count} шаблонов для переназначения", unassigned.Count); + + // Перераспределяем только невалидные + var reassigned = await ScheduleTemplatesAsync(unassigned, startDate, endDate, executionTime); + + // Возвращаем все шаблоны с их датами + var result = templates.Select(t => new TemplateNextRunDto { Id = t.Id, NextRun = t.NextRun!.Value }).ToList(); + + logger.LogInformation("Перераспределение завершено. Возвращаем {Count} записей.", result.Count); + + return result; + } + + + /// + /// Возвращает актуальную дату выполнения для одного шаблона. + /// Результат — список из одного элемента (если успешно) или пустой. + /// + public async Task> GetValidNextRunAsync(TemplateNextRunDto template, DateOnly startDate, DateOnly endDate, TimeSpan executionTime) + { + logger.LogDebug("Запрос актуальной даты для шаблона {TemplateId}", template.Id); + + // Получаем список выходных/праздничных дней + var weekends = (await weekendDayService.GetWeekends(startDate, endDate).ToListAsync()).ToHashSet(); + + var nextRun = await GetValidNextRunInternalAsync(template, startDate, endDate, weekends, executionTime); + if (nextRun.HasValue) + { + logger.LogDebug("Шаблон {TemplateId} имеет актуальную дату {NextRun}", template.Id, nextRun); + return new List { new TemplateNextRunDto { Id = template.Id, NextRun = nextRun.Value } }; + } + + logger.LogWarning("Не удалось получить актуальную дату для шаблона {TemplateId}", template.Id); + return new List(); + } + + + /// + /// Возвращает список актуальных дат выполнения для всех переданных шаблонов. + /// + public async Task> GetValidNextRunsAsync(List templates, DateOnly startDate, DateOnly endDate, TimeSpan executionTime) + { + logger.LogDebug("Запрос актуальных дат для {Count} шаблонов", templates.Count); + + // Получаем список выходных/праздничных дней + var weekends = (await weekendDayService.GetWeekends(startDate, endDate).ToListAsync()).ToHashSet(); + + var result = new List(); + + foreach (var template in templates) + { + var nextRun = await GetValidNextRunInternalAsync(template, startDate, endDate, weekends, executionTime); + if (nextRun.HasValue) + { + result.Add(new TemplateNextRunDto { Id = template.Id, NextRun = nextRun.Value }); + } + } + + logger.LogInformation("Получено {Count} актуальных дат выполнения", result.Count); + + return result; + } + + + /// + /// Внутренний метод для получения актуальной даты выполнения для одного шаблона. + /// + private async Task GetValidNextRunInternalAsync(TemplateNextRunDto template, DateOnly startDate, DateOnly endDate, HashSet weekends, TimeSpan executionTime) + { + var workDays = GetWorkDays(startDate, endDate, weekends); + var today = DateOnly.FromDateTime(DateTime.UtcNow); + + // Если у шаблона нет даты, назначаем первую доступную + if (!template.NextRun.HasValue) + { + var firstDay = workDays.FirstOrDefault(); + if (firstDay != default) + { + var nextRun = new DateTimeOffset(firstDay.Year, firstDay.Month, firstDay.Day, executionTime.Hours, executionTime.Minutes, executionTime.Seconds, TimeSpan.Zero); + logger.LogDebug("Шаблон {TemplateId} получил первую доступную дату: {NextRun}", template.Id, nextRun); + return nextRun; + } + + logger.LogWarning("Нет доступных рабочих дней для шаблона {TemplateId}", template.Id); + return null; + } + + var scheduledDate = DateOnly.FromDateTime(template.NextRun.Value.Date); + + // Если дата валидна и не устарела — возвращаем как есть + if (workDays.Contains(scheduledDate)) + { + if (template.NextRun.Value < DateTimeOffset.UtcNow) + { + logger.LogDebug("Дата шаблона {TemplateId} ({Date}) устарела", template.Id, template.NextRun); + var newDate = FindNextAvailableDate(workDays, today, scheduledDate); + if (newDate.HasValue) + { + var nextRun = new DateTimeOffset(newDate.Value.Year, newDate.Value.Month, newDate.Value.Day, executionTime.Hours, executionTime.Minutes, executionTime.Seconds, TimeSpan.Zero); + logger.LogDebug("Шаблон {TemplateId} перенесен на {NewDate}", template.Id, nextRun); + return nextRun; + } + logger.LogWarning("Не удалось найти новую дату для устаревшего шаблона {TemplateId}", template.Id); + return null; + } + // Дата валидна и не устарела + logger.LogDebug("Шаблон {TemplateId} имеет действительную дату: {NextRun}", template.Id, template.NextRun); + return template.NextRun; + } + + // Дата недействительна (выходной или вне периода) — ищем ближайшую + var closest = FindClosestValidDate(workDays, scheduledDate); + if (closest.HasValue) + { + var nextRun = new DateTimeOffset(closest.Value.Year, closest.Value.Month, closest.Value.Day, executionTime.Hours, executionTime.Minutes, executionTime.Seconds, TimeSpan.Zero); + logger.LogDebug("Шаблон {TemplateId} перемещен на ближайшую дату: {NextRun}", template.Id, nextRun); + return nextRun; + } + + logger.LogWarning("Не удалось найти подходящую дату для шаблона {TemplateId}", template.Id); + return null; + } + + + /// + /// Ищет следующую доступную дату после указанной, если не находит — ищет назад. + /// + private DateOnly? FindNextAvailableDate(List workDays, DateOnly afterDate, DateOnly originalDate) + { + var future = workDays.FirstOrDefault(d => d > afterDate); + + if (future != default) + return future; + + var past = workDays.Where(t => t >= originalDate).OrderByDescending(t => t).FirstOrDefault(); + + return past != default ? (DateOnly?)past : null; + } + + + /// + /// Ищет ближайшую дату (вперед или назад) к заданной, среди доступных рабочих дней. + /// + private DateOnly? FindClosestValidDate(List workDays, DateOnly targetDate) + { + var future = workDays.FirstOrDefault(t => t >= targetDate); + + if (future != default) + return future; + + var past = workDays.Where(t => t <= targetDate).OrderByDescending(t => t).FirstOrDefault(); + + return past != default ? (DateOnly?)past : null; + } + + + /// + /// Возвращает список рабочих дней в диапазоне, исключая выходные и праздники. + /// + private List GetWorkDays(DateOnly start, DateOnly end, HashSet weekends) + { + var result = new List(); + var date = start; + + while (date <= end) + { + if (!weekends.Contains(date)) + { + result.Add(date); + } + date = date.AddDays(1); + } + + return result; + } + } +} diff --git a/PARR.DAL/ParrDalInstaller.cs b/PARR.DAL/ParrDalInstaller.cs index abf7f915..9ba7a052 100644 --- a/PARR.DAL/ParrDalInstaller.cs +++ b/PARR.DAL/ParrDalInstaller.cs @@ -8,6 +8,8 @@ using PARR.DAL.Contracts; using PARR.DAL.DomainServices.Implementations; using PARR.DAL.DomainServices.Interfaces; using PARR.DAL.InfluxDbServices; +using PARR.DAL.NextRunServices; +using PARR.DAL.NextRunServices.Subservices; using PARR.DAL.Services.Implementation; using PARR.DAL.Services.Implementations; using PARR.DAL.Services.Implementations.Job; @@ -17,6 +19,7 @@ using PARR.DAL.Services.Interfaces.Job; using PARR.DAL.Services.Interfaces.Unit; using PARR.DAL.Settings; using PARR.DAL.TransformServices; +using System.ComponentModel; namespace PARR.DAL { @@ -121,6 +124,14 @@ namespace PARR.DAL services.AddTransient(); services.AddTransient(); + #region NextRun Services + + services.AddTransient(); + services.AddTransient(); + + #endregion + + #region DomainServces services.AddTransient(); services.AddTransient(); diff --git a/PARR.DAL/Services/Implementations/WeekendDayService.cs b/PARR.DAL/Services/Implementations/WeekendDayService.cs index 8bb97949..8749532f 100644 --- a/PARR.DAL/Services/Implementations/WeekendDayService.cs +++ b/PARR.DAL/Services/Implementations/WeekendDayService.cs @@ -36,7 +36,7 @@ namespace PARR.DAL.Services.Implementations public IQueryable GetWeekends(DateOnly start, DateOnly end) { - return EntitySet.Where(t => t.Date >= start && t.Date <= end).Select(t => t.Date); + return EntitySet.Where(t => t.Date >= start && t.Date <= end).AsNoTracking().Select(t => t.Date); } diff --git a/PARR.TemplateTaskGenerator/TemplateTaskGenerator.cs b/PARR.TemplateTaskGenerator/TemplateTaskGenerator.cs index 7d3453d0..956827d6 100644 --- a/PARR.TemplateTaskGenerator/TemplateTaskGenerator.cs +++ b/PARR.TemplateTaskGenerator/TemplateTaskGenerator.cs @@ -43,6 +43,7 @@ namespace PARR.TemplateTaskGenerator { var mqRequest = new TemplateGeneratorMq { + UnitsInTemplate=new List(), JobId = jobId, UnitId = unitId, HistoryInitiator = new HistoryInitiator { InitiatorComment = "Запрос на создание шаблона", InitiatorParrComponentId = ParrComponentsEnum.TemplateTaskGenerator } diff --git a/docker-compose.dcproj b/docker-compose.dcproj index 079df966..825b0fcb 100644 --- a/docker-compose.dcproj +++ b/docker-compose.dcproj @@ -10,7 +10,6 @@ - diff --git a/docker-compose.template-task-generator.yml b/docker-compose.template-task-generator.yml deleted file mode 100644 index ac94de89..00000000 --- a/docker-compose.template-task-generator.yml +++ /dev/null @@ -1,27 +0,0 @@ -version: '3.4' - -#PARR TEMPLATE TASK GENERATOR -services: - parr-template-task-generator: - image: harbor.dvgd.rzd/parr/parr-template-task-generator:${tag-latest} - environment: - - ASPNETCORE_ENVIRONMENT=Production - - TZ=Europe/Moscow - logging: - driver: fluentd - options: - fluentd-address: dvgd-efk-01.dvgd.oao.rzd:24224 - fluentd-retry-wait: '10s' - fluentd-max-retries: '30' - fluentd-async: 'true' - fluentd-buffer-limit: '52428800' - tag: parr.template-task-generator.serilog - deploy: - replicas: 1 - networks: - parr-network: - -networks: - parr-network: - driver: overlay - external: true \ No newline at end of file