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);
|
||||
|
||||
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"));
|
||||
|
||||
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": {
|
||||
"ThresholdConnections": 28
|
||||
"ThresholdConnections": 29
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -84,6 +84,8 @@ namespace PARR.Core
|
||||
services.AddScoped<WorkloadCacheService>();
|
||||
services.AddScoped<IWorkloadService, WorkloadService>();
|
||||
|
||||
services.AddSingleton<IWorkloadIntervalService, WorkloadIntervalService>();
|
||||
|
||||
#endregion
|
||||
|
||||
#region NextRun
|
||||
|
||||
@@ -11,7 +11,8 @@ namespace PARR.Core.Services.TaskServices.Interfaces
|
||||
public interface ITaskManagementService
|
||||
{
|
||||
/// <summary>
|
||||
/// Создать новую задачу в БД и опубликовать в очередь
|
||||
/// Создать новую задачу в БД и опубликовать в очередь.
|
||||
/// В случае ошибок генерирует Exception.
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <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.TemplateActivator, Name = ParrComponentsEnum.TemplateActivator.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>
|
||||
/// Генератор Template
|
||||
/// </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);
|
||||
#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();
|
||||
host.Run();
|
||||
|
||||
@@ -3,13 +3,15 @@ using PARR.WorkloadBuilderWorker.Settings;
|
||||
|
||||
namespace PARR.WorkloadBuilderWorker
|
||||
{
|
||||
public class Worker : BackgroundService
|
||||
public class RabbitWorker : BackgroundService
|
||||
{
|
||||
private readonly ILogger<RabbitWorker> logger;
|
||||
private readonly IWorkloadCacheBuilderService workloadCacheBuilderService;
|
||||
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.workerSettings = WorkerSettings;
|
||||
}
|
||||
@@ -17,6 +19,7 @@ namespace PARR.WorkloadBuilderWorker
|
||||
|
||||
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
|
||||
{
|
||||
logger.LogInformation("Запуск {workerName}", nameof(RabbitWorker));
|
||||
await workloadCacheBuilderService.ProcessMessagesAsync(workerSettings.MqSettings);
|
||||
}
|
||||
|
||||
@@ -4,6 +4,14 @@ namespace PARR.WorkloadBuilderWorker.Settings
|
||||
{
|
||||
public record WorkerSettings
|
||||
{
|
||||
/// <summary>
|
||||
/// Настройки MQ
|
||||
/// </summary>
|
||||
public MqSettingsBase MqSettings { get; init; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// Интервал повторений
|
||||
/// </summary>
|
||||
public TimeSpan RepeatEvery { get; init; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
"QueueName": "parr-task-workload",
|
||||
"User": "task_workload_reader",
|
||||
"Password": "sdjfgIYFdifyKJFDhvsad@!314d"
|
||||
}
|
||||
},
|
||||
"RepeatEvery": "12:00:00"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
<DockerServiceName>parr.api</DockerServiceName>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<None Include="docker-compose.task-reconciliation.yml" />
|
||||
<None Include="docker-compose.template-matcher.yml" />
|
||||
<None Include="docker-compose.template-generator.yml" />
|
||||
<None Include="docker-compose.aihit-loader.yml" />
|
||||
@@ -25,6 +26,7 @@
|
||||
<None Include="docker-compose.template-activator.yml" />
|
||||
<None Include="docker-compose.template-distributor.yml" />
|
||||
<None Include="docker-compose.template-updater.yml" />
|
||||
<None Include="docker-compose.workload-builder.yml" />
|
||||
<None Include="docker-compose.yml" />
|
||||
<None Include=".dockerignore" />
|
||||
<None Include="stack.yml" />
|
||||
|
||||
@@ -2,11 +2,13 @@ version: '3.4'
|
||||
|
||||
# workload builder
|
||||
services:
|
||||
parr-workload-builder:
|
||||
parr-workload-builder-interval:
|
||||
image: harbor.dvgd.rzd/parr/parr-workload-builder:${tag:-latest}
|
||||
environment:
|
||||
- ASPNETCORE_ENVIRONMENT=Production
|
||||
- TZ=Europe/Moscow
|
||||
- ENABLE_RABBIT=false
|
||||
- ENABLE_INTERVAL=true
|
||||
logging:
|
||||
driver: fluentd
|
||||
options:
|
||||
@@ -15,7 +17,28 @@ services:
|
||||
fluentd-max-retries: '30'
|
||||
fluentd-async: 'true'
|
||||
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:
|
||||
replicas: 1
|
||||
networks:
|
||||
|
||||
Reference in New Issue
Block a user