feat(docker, api, core, dal, domain, workloadBuilder): WorkloadBuillder - формирование кэша по интервалу.
This commit is contained in:
@@ -137,7 +137,6 @@ namespace PARR.API.Controllers.V1.Statistics
|
|||||||
var report = await workloadService.GetWorkloadReport(reportType, dateStart, durationDays, offset, filter);
|
var report = await workloadService.GetWorkloadReport(reportType, dateStart, durationDays, offset, filter);
|
||||||
|
|
||||||
if (report == null)
|
if (report == null)
|
||||||
//return BadRequest(new Response(false, new List<ErrorModel> { new ErrorModel { Message = "Необходимо сформировать отчетность." } }));
|
|
||||||
return BadRequest(new Response<string?>(null, false, new List<ErrorModel> { new ErrorModel { Message = "Необходимо сформировать отчетность." } }, "empty"));
|
return BadRequest(new Response<string?>(null, false, new List<ErrorModel> { new ErrorModel { Message = "Необходимо сформировать отчетность." } }, "empty"));
|
||||||
|
|
||||||
var resonse = mapper.Map<StatWorkloadReportResponse>(report);
|
var resonse = mapper.Map<StatWorkloadReportResponse>(report);
|
||||||
|
|||||||
@@ -0,0 +1,9 @@
|
|||||||
|
using Microsoft.AspNetCore.Diagnostics;
|
||||||
|
|
||||||
|
namespace PARR.API.Infrastructure.Middleware
|
||||||
|
{
|
||||||
|
public class GlobalExceptionHandler//: IExceptionHandler
|
||||||
|
{
|
||||||
|
//todo:
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -111,7 +111,7 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"RabbitMq": {
|
"RabbitMq": {
|
||||||
"ThresholdConnections": 28
|
"ThresholdConnections": 29
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -84,6 +84,8 @@ namespace PARR.Core
|
|||||||
services.AddScoped<WorkloadCacheService>();
|
services.AddScoped<WorkloadCacheService>();
|
||||||
services.AddScoped<IWorkloadService, WorkloadService>();
|
services.AddScoped<IWorkloadService, WorkloadService>();
|
||||||
|
|
||||||
|
services.AddSingleton<IWorkloadIntervalService, WorkloadIntervalService>();
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region NextRun
|
#region NextRun
|
||||||
|
|||||||
@@ -11,7 +11,8 @@ namespace PARR.Core.Services.TaskServices.Interfaces
|
|||||||
public interface ITaskManagementService
|
public interface ITaskManagementService
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Создать новую задачу в БД и опубликовать в очередь
|
/// Создать новую задачу в БД и опубликовать в очередь.
|
||||||
|
/// В случае ошибок генерирует Exception.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <typeparam name="T"></typeparam>
|
/// <typeparam name="T"></typeparam>
|
||||||
/// <param name="typeCode">Тип задачи</param>
|
/// <param name="typeCode">Тип задачи</param>
|
||||||
|
|||||||
@@ -0,0 +1,55 @@
|
|||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
using PARR.Core.Common.Interfaces;
|
||||||
|
using PARR.Core.Services.TaskServices.Interfaces;
|
||||||
|
using PARR.Core.Services.Workload.Interfaces;
|
||||||
|
using PARR.Domain.Entities.Base.History;
|
||||||
|
using PARR.Domain.Settings;
|
||||||
|
|
||||||
|
namespace PARR.Core.Services.Workload.Implementations
|
||||||
|
{
|
||||||
|
internal class WorkloadIntervalService : IWorkloadIntervalService
|
||||||
|
{
|
||||||
|
private readonly ILogger<WorkloadIntervalService> logger;
|
||||||
|
private readonly IIntervalService intervalService;
|
||||||
|
private readonly IServiceProvider serviceProvider;
|
||||||
|
|
||||||
|
public WorkloadIntervalService(
|
||||||
|
ILogger<WorkloadIntervalService> logger,
|
||||||
|
IIntervalService intervalService,
|
||||||
|
IServiceProvider serviceProvider
|
||||||
|
)
|
||||||
|
{
|
||||||
|
this.logger = logger;
|
||||||
|
this.intervalService = intervalService;
|
||||||
|
this.serviceProvider = serviceProvider;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task StartAsync(TimeSpan interval, IMqSettings mqSettings)
|
||||||
|
{
|
||||||
|
logger.LogInformation("Запуск сервиса формирования кэш отчетов Workload по интервалу.");
|
||||||
|
|
||||||
|
await intervalService.IntervalInitAsync(async () =>
|
||||||
|
{
|
||||||
|
|
||||||
|
await using (var scope = serviceProvider.CreateAsyncScope())
|
||||||
|
{
|
||||||
|
var taskManagementService = scope.ServiceProvider.GetRequiredService<ITaskManagementService>();
|
||||||
|
|
||||||
|
var initiator = new HistoryInitiator { InitiatorParrComponentId = Domain.Enums.ParrComponentsEnum.WorkloadBuilder, InitiatorComment = $"Генерация кэш workload по интервалу '{interval}'" };
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var taskId = await taskManagementService.CreateTaskAsync<object?>(Domain.Enums.TaskTypeEnum.Workload, default, initiator, mqSettings);
|
||||||
|
logger.LogInformation("Создана задача {taskId} на формирование кэш отчета.", taskId);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
logger.LogError(ex, "Ошибка при отправке задания на формирование кэш отчета.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}, interval);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
using PARR.Domain.Settings;
|
||||||
|
|
||||||
|
namespace PARR.Core.Services.Workload.Interfaces
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Формирование кэш отчетов по интервалу
|
||||||
|
/// </summary>
|
||||||
|
public interface IWorkloadIntervalService
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Запуск формирования по интервалу
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="interval">Интервал</param>
|
||||||
|
/// <param name="mqSettings">Настройки очереди куда отправлять задание</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
Task StartAsync(TimeSpan interval, IMqSettings mqSettings);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -518,7 +518,8 @@ namespace PARR.DAL.Context
|
|||||||
new() { Id = ParrComponentsEnum.NextRun, Name = ParrComponentsEnum.NextRun.ToString(), Description = "Рассчет даты следующего срабатывания" },
|
new() { Id = ParrComponentsEnum.NextRun, Name = ParrComponentsEnum.NextRun.ToString(), Description = "Рассчет даты следующего срабатывания" },
|
||||||
new() { Id = ParrComponentsEnum.TemplateActivator, Name = ParrComponentsEnum.TemplateActivator.ToString(), Description = "Активатор шаблонов / расписаний" },
|
new() { Id = ParrComponentsEnum.TemplateActivator, Name = ParrComponentsEnum.TemplateActivator.ToString(), Description = "Активатор шаблонов / расписаний" },
|
||||||
new() { Id = ParrComponentsEnum.TemplateDistributor, Name = ParrComponentsEnum.TemplateDistributor.ToString(), Description = "Автораспределение РР" },
|
new() { Id = ParrComponentsEnum.TemplateDistributor, Name = ParrComponentsEnum.TemplateDistributor.ToString(), Description = "Автораспределение РР" },
|
||||||
new() { Id = ParrComponentsEnum.TemplateTaskGenerator, Name = ParrComponentsEnum.TemplateTaskGenerator.ToString(), Description = "Генератор шаблонов" }
|
new() { Id = ParrComponentsEnum.TemplateTaskGenerator, Name = ParrComponentsEnum.TemplateTaskGenerator.ToString(), Description = "Генератор шаблонов" },
|
||||||
|
new() { Id = ParrComponentsEnum.WorkloadBuilder, Name = ParrComponentsEnum.WorkloadBuilder.ToString(), Description = "Генератор кэша отчетов workload" }
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -79,6 +79,11 @@ namespace PARR.Domain.Enums
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Генератор Template
|
/// Генератор Template
|
||||||
/// </summary>
|
/// </summary>
|
||||||
TemplateTaskGenerator = 13
|
TemplateTaskGenerator = 13,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Генератор кэша отчетов Workload
|
||||||
|
/// </summary>
|
||||||
|
WorkloadBuilder = 14
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
25
PARR.WorkloadBuilderWorker/IntervalWorker.cs
Normal file
25
PARR.WorkloadBuilderWorker/IntervalWorker.cs
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
using PARR.Core.Services.Workload.Interfaces;
|
||||||
|
using PARR.WorkloadBuilderWorker.Settings;
|
||||||
|
|
||||||
|
namespace PARR.WorkloadBuilderWorker
|
||||||
|
{
|
||||||
|
public class IntervalWorker : BackgroundService
|
||||||
|
{
|
||||||
|
private readonly ILogger<IntervalWorker> logger;
|
||||||
|
private readonly IWorkloadIntervalService workloadIntervalService;
|
||||||
|
private readonly WorkerSettings workerSettings;
|
||||||
|
|
||||||
|
public IntervalWorker(ILogger<IntervalWorker> logger, IWorkloadIntervalService workloadIntervalService, WorkerSettings workerSettings)
|
||||||
|
{
|
||||||
|
this.logger = logger;
|
||||||
|
this.workloadIntervalService = workloadIntervalService;
|
||||||
|
this.workerSettings = workerSettings;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
|
||||||
|
{
|
||||||
|
logger.LogInformation("Запуск {workerName}", nameof(IntervalWorker));
|
||||||
|
await workloadIntervalService.StartAsync(workerSettings.RepeatEvery, workerSettings.MqSettings);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -46,8 +46,25 @@ builder.Configuration.AddDalConfigurations(builder.Services);
|
|||||||
builder.Services.AddDallSettings(builder.Configuration);
|
builder.Services.AddDallSettings(builder.Configuration);
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
// Задается через переменные окружеия
|
||||||
|
var runRabbit = builder.Configuration.GetValue<bool>("ENABLE_RABBIT", true);
|
||||||
|
var runInterval = builder.Configuration.GetValue<bool>("ENABLE_INTERVAL", true);
|
||||||
|
|
||||||
builder.Services.AddHostedService<Worker>();
|
if (runRabbit)
|
||||||
|
{
|
||||||
|
builder.Services.AddHostedService<RabbitWorker>();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (runInterval)
|
||||||
|
{
|
||||||
|
builder.Services.AddHostedService<IntervalWorker>();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Настройка краша при ошибке. Если хоть один из воркеров упадет, то падает целиком проект
|
||||||
|
builder.Services.Configure<HostOptions>(options =>
|
||||||
|
{
|
||||||
|
options.BackgroundServiceExceptionBehavior = BackgroundServiceExceptionBehavior.StopHost;
|
||||||
|
});
|
||||||
|
|
||||||
var host = builder.Build();
|
var host = builder.Build();
|
||||||
host.Run();
|
host.Run();
|
||||||
|
|||||||
@@ -3,13 +3,15 @@ using PARR.WorkloadBuilderWorker.Settings;
|
|||||||
|
|
||||||
namespace PARR.WorkloadBuilderWorker
|
namespace PARR.WorkloadBuilderWorker
|
||||||
{
|
{
|
||||||
public class Worker : BackgroundService
|
public class RabbitWorker : BackgroundService
|
||||||
{
|
{
|
||||||
|
private readonly ILogger<RabbitWorker> logger;
|
||||||
private readonly IWorkloadCacheBuilderService workloadCacheBuilderService;
|
private readonly IWorkloadCacheBuilderService workloadCacheBuilderService;
|
||||||
private readonly WorkerSettings workerSettings;
|
private readonly WorkerSettings workerSettings;
|
||||||
|
|
||||||
public Worker(ILogger<Worker> logger, IWorkloadCacheBuilderService workloadCacheBuilderService, WorkerSettings WorkerSettings)
|
public RabbitWorker(ILogger<RabbitWorker> logger, IWorkloadCacheBuilderService workloadCacheBuilderService, WorkerSettings WorkerSettings)
|
||||||
{
|
{
|
||||||
|
this.logger = logger;
|
||||||
this.workloadCacheBuilderService = workloadCacheBuilderService;
|
this.workloadCacheBuilderService = workloadCacheBuilderService;
|
||||||
this.workerSettings = WorkerSettings;
|
this.workerSettings = WorkerSettings;
|
||||||
}
|
}
|
||||||
@@ -17,6 +19,7 @@ namespace PARR.WorkloadBuilderWorker
|
|||||||
|
|
||||||
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
|
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
|
||||||
{
|
{
|
||||||
|
logger.LogInformation("Запуск {workerName}", nameof(RabbitWorker));
|
||||||
await workloadCacheBuilderService.ProcessMessagesAsync(workerSettings.MqSettings);
|
await workloadCacheBuilderService.ProcessMessagesAsync(workerSettings.MqSettings);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4,6 +4,14 @@ namespace PARR.WorkloadBuilderWorker.Settings
|
|||||||
{
|
{
|
||||||
public record WorkerSettings
|
public record WorkerSettings
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Настройки MQ
|
||||||
|
/// </summary>
|
||||||
public MqSettingsBase MqSettings { get; init; } = new();
|
public MqSettingsBase MqSettings { get; init; } = new();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Интервал повторений
|
||||||
|
/// </summary>
|
||||||
|
public TimeSpan RepeatEvery { get; init; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,6 +28,7 @@
|
|||||||
"QueueName": "parr-task-workload",
|
"QueueName": "parr-task-workload",
|
||||||
"User": "task_workload_reader",
|
"User": "task_workload_reader",
|
||||||
"Password": "sdjfgIYFdifyKJFDhvsad@!314d"
|
"Password": "sdjfgIYFdifyKJFDhvsad@!314d"
|
||||||
}
|
},
|
||||||
|
"RepeatEvery": "12:00:00"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
<DockerServiceName>parr.api</DockerServiceName>
|
<DockerServiceName>parr.api</DockerServiceName>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<None Include="docker-compose.task-reconciliation.yml" />
|
||||||
<None Include="docker-compose.template-matcher.yml" />
|
<None Include="docker-compose.template-matcher.yml" />
|
||||||
<None Include="docker-compose.template-generator.yml" />
|
<None Include="docker-compose.template-generator.yml" />
|
||||||
<None Include="docker-compose.aihit-loader.yml" />
|
<None Include="docker-compose.aihit-loader.yml" />
|
||||||
@@ -25,6 +26,7 @@
|
|||||||
<None Include="docker-compose.template-activator.yml" />
|
<None Include="docker-compose.template-activator.yml" />
|
||||||
<None Include="docker-compose.template-distributor.yml" />
|
<None Include="docker-compose.template-distributor.yml" />
|
||||||
<None Include="docker-compose.template-updater.yml" />
|
<None Include="docker-compose.template-updater.yml" />
|
||||||
|
<None Include="docker-compose.workload-builder.yml" />
|
||||||
<None Include="docker-compose.yml" />
|
<None Include="docker-compose.yml" />
|
||||||
<None Include=".dockerignore" />
|
<None Include=".dockerignore" />
|
||||||
<None Include="stack.yml" />
|
<None Include="stack.yml" />
|
||||||
|
|||||||
@@ -2,11 +2,13 @@ version: '3.4'
|
|||||||
|
|
||||||
# workload builder
|
# workload builder
|
||||||
services:
|
services:
|
||||||
parr-workload-builder:
|
parr-workload-builder-interval:
|
||||||
image: harbor.dvgd.rzd/parr/parr-workload-builder:${tag:-latest}
|
image: harbor.dvgd.rzd/parr/parr-workload-builder:${tag:-latest}
|
||||||
environment:
|
environment:
|
||||||
- ASPNETCORE_ENVIRONMENT=Production
|
- ASPNETCORE_ENVIRONMENT=Production
|
||||||
- TZ=Europe/Moscow
|
- TZ=Europe/Moscow
|
||||||
|
- ENABLE_RABBIT=false
|
||||||
|
- ENABLE_INTERVAL=true
|
||||||
logging:
|
logging:
|
||||||
driver: fluentd
|
driver: fluentd
|
||||||
options:
|
options:
|
||||||
@@ -15,7 +17,28 @@ services:
|
|||||||
fluentd-max-retries: '30'
|
fluentd-max-retries: '30'
|
||||||
fluentd-async: 'true'
|
fluentd-async: 'true'
|
||||||
fluentd-buffer-limit: '52428800'
|
fluentd-buffer-limit: '52428800'
|
||||||
tag: parr.workload-builder.serilog
|
tag: parr.workload-builder-interval.serilog
|
||||||
|
deploy:
|
||||||
|
replicas: 1
|
||||||
|
networks:
|
||||||
|
- parr-network
|
||||||
|
|
||||||
|
parr-workload-builder-rabbit:
|
||||||
|
image: harbor.dvgd.rzd/parr/parr-workload-builder:${tag:-latest}
|
||||||
|
environment:
|
||||||
|
- ASPNETCORE_ENVIRONMENT=Production
|
||||||
|
- TZ=Europe/Moscow
|
||||||
|
- ENABLE_RABBIT=true
|
||||||
|
- ENABLE_INTERVAL=false
|
||||||
|
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.workload-builder-rabbit.serilog
|
||||||
deploy:
|
deploy:
|
||||||
replicas: 1
|
replicas: 1
|
||||||
networks:
|
networks:
|
||||||
|
|||||||
Reference in New Issue
Block a user