From 24759bb3e0f83707c1af4489506847b22b246b31 Mon Sep 17 00:00:00 2001 From: Mikhail Trubnikov Date: Tue, 9 Dec 2025 08:40:05 +1000 Subject: [PATCH] =?UTF-8?q?feat(job-auto-control):=20=D0=9F=D0=B5=D1=80?= =?UTF-8?q?=D0=B5=D0=B4=D0=B5=D0=BB=D0=B0=D0=BB=20=D1=81=D0=BE=D0=B3=D0=BB?= =?UTF-8?q?=D0=B0=D1=81=D0=BD=D0=BE=20=D0=BD=D0=BE=D0=B2=D0=BE=D0=B9=20?= =?UTF-8?q?=D1=81=D1=82=D1=80=D1=83=D0=BA=D1=82=D1=83=D1=80=D1=8B.=20?= =?UTF-8?q?=D0=9E=D1=82=D0=BF=D1=80=D0=B0=D0=B2=D0=BB=D1=8F=D0=B5=D1=82=20?= =?UTF-8?q?=D0=B7=D0=B0=D0=B4=D0=B0=D0=BD=D0=B8=D1=8F=20=D0=B2=20matcher.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- PARR.JobAutoControl/JobAutoControlManager.cs | 195 ++++-------------- PARR.JobAutoControl/Settings/MqSettings.cs | 13 +- PARR.JobAutoControlWorker/Dockerfile | 11 +- PARR.JobAutoControlWorker/Worker.cs | 1 + .../appsettings.Development.json | 5 +- PARR.JobAutoControlWorker/appsettings.json | 14 +- 6 files changed, 59 insertions(+), 180 deletions(-) diff --git a/PARR.JobAutoControl/JobAutoControlManager.cs b/PARR.JobAutoControl/JobAutoControlManager.cs index 0d5c2825..b6bd5e97 100644 --- a/PARR.JobAutoControl/JobAutoControlManager.cs +++ b/PARR.JobAutoControl/JobAutoControlManager.cs @@ -3,9 +3,7 @@ using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using PARR.BLL.Domain.Mq; using PARR.BLL.Services.Interfaces; -using PARR.Common.Domain; -using PARR.Constants; -using PARR.DAL.Services.Interfaces; +using PARR.DAL.Services.Interfaces.Job; using PARR.JobAutoControl.Settings; using System.Text.Json; @@ -36,166 +34,59 @@ namespace PARR.JobAutoControl public async Task StartAsync() { - //logger.LogInformation("Запуск сервиса управления авто-контролем РР (JobAutoControl)"); + logger.LogInformation("Запуск сервиса управления авто-контролем РР (JobAutoControl)"); - //await intervalService.IntervalInitAsync(async () => - //{ - // using (var scope = serviceProvider.CreateScope()) - // { - // var jobAutoControlService = scope.ServiceProvider.GetService(); - // var mqService = scope.ServiceProvider.GetService(); + await intervalService.IntervalInitAsync(async () => + { + await using (var scope = serviceProvider.CreateAsyncScope()) + //using (var scope = serviceProvider.CreateScope()) + { + var jobAutoControlService = scope.ServiceProvider.GetService(); + var mqService = scope.ServiceProvider.GetService(); - // if (jobAutoControlService == null || mqService == null) - // throw new Exception($"Не смог получить серивс {nameof(IJobAutoControlService)} или {nameof(IMqService)}"); + if (jobAutoControlService == null || mqService == null) + throw new Exception($"Не смог получить серивс {nameof(IJobAutoControlService)} или {nameof(IMqService)}"); - // await HandlerAsync(jobAutoControlService, mqService); - // } - //}, workerSettings.RepeatEvery); + await HandlerAsync(jobAutoControlService, mqService); + } + }, workerSettings.RepeatEvery); } - //private async Task HandlerAsync(IJobAutoControlService jobAutoControlService, IMqService mqService) - //{ - // await GenerateAsync(jobAutoControlService, mqService); - // await DeactivateAsync(jobAutoControlService, mqService); - // await ActivateAsync(jobAutoControlService, mqService); - //} + private async Task HandlerAsync(IJobAutoControlService jobAutoControlService, IMqService mqService) + { + var jobsWithAutoControl = await jobAutoControlService.Get().Where(t => t.IsEnable).ToListAsync(); + + logger.LogInformation($"Работ с включенным авто-контролем: {jobsWithAutoControl.Count} шт."); + + if (jobsWithAutoControl.Count == 0) + return; - ///// - ///// Генерировать новые РР - ///// - ///// - ///// - ///// - //private async Task GenerateAsync(IJobAutoControlService jobAutoControlService, IMqService mqService) - //{ - // var jobsToGenerate = await jobAutoControlService.Get() - // .Include(t => t.JobEkMasks) - // .Include(t => t.JobAutoControlInEkStatuses) - // .Include(t => t.ApplicationsInWork) - // .Where(t => t.CreateNew && t.JobEkMasks.Any() && t.JobAutoControlInEkStatuses.Any()) - // .ToListAsync(); + // формируем сообщения + var msgList = jobsWithAutoControl.Select(t => new TemplateMatcherMq + { + Action = Constants.TemplateMatcherActionEnum.Sync, + EntityType = Constants.SyncTaskEntityTypeEnum.Job, + Id = t.JobId, + Initiator = new Common.Domain.HistoryInitiator + { + InitiatorComment = $"Инициатор авто-контроль, периодичность: {workerSettings.RepeatEvery}", + InitiatorIp = null, + InitiatorParrComponentId = Constants.ParrComponentsEnum.JobAutoControl + } + }); - // logger.LogInformation($"Найдено РР с включенным авто-контролем для генерации шаблонов и расписаний: {jobsToGenerate.Count()} шт."); + var msgStrList = msgList.Select(t => JsonSerializer.Serialize(t)); - // if (!jobsToGenerate.Any()) - // return; + // отправляем задания в очередь template matcher`a + var sendResult = await mqService.SendAsync(mqSettings.TemplateMatcher, msgStrList.ToArray()); - - // jobsToGenerate.ForEach(job => - // { - // job.JobEkMasks.ToList().ForEach(ek => - // { - // //todo: проверить, нормально ли отрабатывает async в Foreach - // job.JobAutoControlInEkStatuses.ToList().ForEach(async ekStatus => - // { - // var request = new GeneratorTemplateMq - // { - // Action = "create", - // ApplicationId = job.ApplicationsInWork!.ApplicationId, - // Ek = ek.Name, - // WorkId = job.ApplicationsInWork!.WorkId, - // StatusEk = ekStatus.EkStatusCode, - // IsActiveTemplate = job.OnTemplateIsActive, - // IsActiveSchedule = job.OnScheduleIsActive, - // HistoryInitiator = new HistoryInitiator { InitiatorComment = "Запрос на генерацию с авто-контроля", InitiatorParrComponentId = ParrComponentsEnum.JobAutoControl } - // }; - - // var msg = JsonSerializer.Serialize(request); - - // var result = await mqService.SendAsync(mqSettings.Generator, new[] { msg }); - - // if (result.IsSuccess) - // logger.LogInformation($"Отправлен запрос на генерацию: {msg}"); - // else - // logger.LogError($"Ошибка при отправке запроса на генерацию: {msg}"); - // }); - // }); - // }); - //} - - - ///// - ///// Деактивировать РР - ///// - ///// - ///// - ///// - //private async Task DeactivateAsync(IJobAutoControlService jobAutoControlService, IMqService mqService) - //{ - // //var jobsToDeactivate = await jobAutoControlService.Get() - // // .Include(t => t.JobEkMasks) - // // .Include(t => t.JobAutoControlInEkStatuses) - // // .Where(t => t.Deactivate && t.JobEkMasks.Any() && t.JobAutoControlInEkStatuses.Any()) - // // .Select(t => t.ApplicationInWorkId) - // // .ToListAsync(); - - // //logger.LogInformation($"Найдено РР с включенным авто-контролем для деактивации шаблонов и расписаний: {jobsToDeactivate.Count()} шт."); - - // //if (!jobsToDeactivate.Any()) - // // return; - - // ////todo: проверить, нормально ли отрабатывает async в foreach - // //jobsToDeactivate.ForEach(async applicationInWorkId => - // //{ - // // var request = new TemplateActivatorMq - // // { - // // Action = TemplateActivatorActionsEnum.DeactivateAllForAutoControl, - // // JobId = applicationInWorkId, - // // HistoryInitiator = new HistoryInitiator { InitiatorComment = "Запрос на деактивацию с авто-контроля", InitiatorParrComponentId = ParrComponentsEnum.JobAutoControl } - // // }; - - // // var msg = JsonSerializer.Serialize(request); - - // // var result = await mqService.SendAsync(mqSettings.Activator, new[] { msg }); - - // // if (result.IsSuccess) - // // logger.LogInformation($"Отправлен запрос на деактивацию: {msg}"); - // // else - // // logger.LogError($"Ошибка при отправке запроса на деактивацию: {msg}"); - // //}); - //} - - - ///// - ///// Активировать РР - ///// - ///// - ///// - ///// - //private async Task ActivateAsync(IJobAutoControlService jobAutoControlService, IMqService mqService) - //{ - // // var jobsToActivate = await jobAutoControlService.Get() - // // .Include(t => t.JobEkMasks) - // // .Include(t => t.JobAutoControlInEkStatuses) - // // .Where(t => t.Activate && t.JobEkMasks.Any() && t.JobAutoControlInEkStatuses.Any()) - // // .Select(t => t.ApplicationInWorkId) - // // .ToListAsync(); - - // // if (!jobsToActivate.Any()) - // // return; - - // // //todo: проверить, нормально ли отрабатывает async в foreach - // // jobsToActivate.ForEach(async applicationInWorkId => - // // { - // // var request = new TemplateActivatorMq - // // { - // // Action = TemplateActivatorActionsEnum.ActivateAllForAutoControl, - // // JobId = applicationInWorkId, - // // HistoryInitiator = new HistoryInitiator { InitiatorComment = "Запрос на активацию с авто-контроля", InitiatorParrComponentId = ParrComponentsEnum.JobAutoControl } - // // }; - - // // var msg = JsonSerializer.Serialize(request); - - // // var result = await mqService.SendAsync(mqSettings.Activator, new[] { msg }); - - // // if (result.IsSuccess) - // // logger.LogInformation($"Отправлен запрос на активацию: {msg}"); - // // else - // // logger.LogError($"Ошибка при отправке запроса на активацию: {msg}"); - // // }); - //} + if (!sendResult.IsSuccess) + logger.LogError($"Ошибка при отправке сообщений ({msgStrList.Count()} шт.) в очередь."); + else + logger.LogInformation($"Выполнена отправка сообщений в очередь, {msgStrList.Count()} шт."); + } } } diff --git a/PARR.JobAutoControl/Settings/MqSettings.cs b/PARR.JobAutoControl/Settings/MqSettings.cs index 097fe9c0..34202d71 100644 --- a/PARR.JobAutoControl/Settings/MqSettings.cs +++ b/PARR.JobAutoControl/Settings/MqSettings.cs @@ -4,11 +4,10 @@ namespace PARR.JobAutoControl.Settings { internal class MqSettings { - public Generator Generator { get; set; } - public Activator Activator { get; set; } + public TemplateMatcher TemplateMatcher { get; set; } = new TemplateMatcher(); } - internal class Generator : IMqSettings + internal class TemplateMatcher : IMqSettings { public string HostName { get; set; } = string.Empty; public string QueueName { get; set; } = string.Empty; @@ -17,14 +16,6 @@ namespace PARR.JobAutoControl.Settings public ushort? PrefetchCount { get; set; } = 0; } - internal class Activator : IMqSettings - { - public string HostName { get; set; } = string.Empty; - public string QueueName { get; set; } = string.Empty; - public string User { get; set; } = string.Empty; - public string Password { get; set; } = string.Empty; - public ushort? PrefetchCount { get; set; } = 0; - } } diff --git a/PARR.JobAutoControlWorker/Dockerfile b/PARR.JobAutoControlWorker/Dockerfile index 08ea960c..a86e24bd 100644 --- a/PARR.JobAutoControlWorker/Dockerfile +++ b/PARR.JobAutoControlWorker/Dockerfile @@ -1,8 +1,11 @@ -#See https://aka.ms/customizecontainer to learn how to customize your debug container and how Visual Studio uses this Dockerfile to build your images for faster debugging. +# See https://aka.ms/customizecontainer to learn how to customize your debug container and how Visual Studio uses this Dockerfile to build your images for faster debugging. +# This stage is used when running from VS in fast mode (Default for Debug configuration) FROM 10.99.253.167:8090/dotnet/runtime:7.0 AS base WORKDIR /app + +# This stage is used to build the service project FROM 10.99.253.167:8090/dotnet/sdk:7.0 AS build ARG BUILD_CONFIGURATION=Release WORKDIR /src @@ -10,19 +13,21 @@ COPY ["NuGet.config", "."] COPY ["PARR.JobAutoControlWorker/PARR.JobAutoControlWorker.csproj", "PARR.JobAutoControlWorker/"] COPY ["PARR.JobAutoControl/PARR.JobAutoControl.csproj", "PARR.JobAutoControl/"] COPY ["PARR.BLL/PARR.BLL.csproj", "PARR.BLL/"] -COPY ["PARR.Constants/PARR.Constants.csproj", "PARR.Constants/"] COPY ["PARR.Common/PARR.Common.csproj", "PARR.Common/"] +COPY ["PARR.Constants/PARR.Constants.csproj", "PARR.Constants/"] COPY ["PARR.DAL/PARR.DAL.csproj", "PARR.DAL/"] RUN dotnet restore "./PARR.JobAutoControlWorker/PARR.JobAutoControlWorker.csproj" COPY . . WORKDIR "/src/PARR.JobAutoControlWorker" RUN dotnet build "./PARR.JobAutoControlWorker.csproj" -c $BUILD_CONFIGURATION -o /app/build +# This stage is used to publish the service project to be copied to the final stage FROM build AS publish -ARG app_version=0.0.0-default ARG BUILD_CONFIGURATION=Release +ARG app_version=0.0.0-default RUN dotnet publish "./PARR.JobAutoControlWorker.csproj" -c $BUILD_CONFIGURATION -o /app/publish /p:UseAppHost=false /p:Version=$app_version +# This stage is used in production or when running from VS in regular mode (Default when not using the Debug configuration) FROM base AS final WORKDIR /app COPY --from=publish /app/publish . diff --git a/PARR.JobAutoControlWorker/Worker.cs b/PARR.JobAutoControlWorker/Worker.cs index 7ac9a80d..e3bc5319 100644 --- a/PARR.JobAutoControlWorker/Worker.cs +++ b/PARR.JobAutoControlWorker/Worker.cs @@ -14,6 +14,7 @@ namespace PARR.JobAutoControlWorker protected override async Task ExecuteAsync(CancellationToken stoppingToken) { await jobAutoControlManager.StartAsync(); + await Task.Delay(Timeout.Infinite, stoppingToken); } } } diff --git a/PARR.JobAutoControlWorker/appsettings.Development.json b/PARR.JobAutoControlWorker/appsettings.Development.json index 709394af..4cf4419a 100644 --- a/PARR.JobAutoControlWorker/appsettings.Development.json +++ b/PARR.JobAutoControlWorker/appsettings.Development.json @@ -27,10 +27,7 @@ ] }, "MqSettings": { - "Generator": { - "HostName": "10.99.253.216" - }, - "Activator": { + "TemplateMatcher": { "HostName": "10.99.253.216" } } diff --git a/PARR.JobAutoControlWorker/appsettings.json b/PARR.JobAutoControlWorker/appsettings.json index 6e12c6f5..8275475f 100644 --- a/PARR.JobAutoControlWorker/appsettings.json +++ b/PARR.JobAutoControlWorker/appsettings.json @@ -22,17 +22,11 @@ "RepeatEvery": "6:00:00" }, "MqSettings": { - "Generator": { + "TemplateMatcher": { "HostName": "parr-rabbitmq", - "QueueName": "parr-generate-templates", - "User": "generate_templates_api", - "Password": "DHhjgdsf*&%95" - }, - "Activator": { - "HostName": "parr-rabbitmq", - "QueueName": "parr-template-activator", - "User": "template_activator_writer", - "Password": "Gfkjhsdg*%fsdf" + "QueueName": "parr-template-matcher", + "User": "template_matcher_writer", + "Password": "8ndd%BpP61Ias;ldk23CkvZM" } } }