Files
parr_api/PARR.NextRun/NextRunManager.cs

249 lines
14 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using PARR.BLL.Services.Interfaces;
using PARR.Common.Domain;
using PARR.Constants;
using PARR.DAL.NextRunServices;
using PARR.DAL.Services.Interfaces;
using PARR.DAL.Services.Interfaces.Job;
using PARR.NextRun.Settings;
namespace PARR.NextRun
{
internal class NextRunManager : INextRunManager
{
private readonly WorkerSettings workerSettings;
private readonly ILogger<NextRunManager> logger;
private readonly IIntervalService intervalService;
private readonly IServiceProvider serviceProvider;
public NextRunManager(
WorkerSettings workerSettings,
ILogger<NextRunManager> logger,
IIntervalService intervalService,
IServiceProvider serviceProvider
)
{
this.workerSettings = workerSettings;
this.logger = logger;
this.intervalService = intervalService;
this.serviceProvider = serviceProvider;
}
public async Task StartAsync()
{
logger.LogInformation("Запуск сервиса рассчета времени следующего создания наряда (nextRun)");
await intervalService.IntervalInitAsync(async () =>
{
using (var scope = serviceProvider.CreateScope())
{
//var appInWorkService = scope.ServiceProvider.GetService<IApplicationsInWorkService>();
//var esppSchService = scope.ServiceProvider.GetService<IEsppScheduleTransformService>();
var templateService = scope.ServiceProvider.GetService<ITemplateService>();
var jobGroupService = scope.ServiceProvider.GetService<IJobGroupService>();
var nextRunService = scope.ServiceProvider.GetService<INextRunService>();
if (templateService == null || nextRunService == null || jobGroupService == null)
throw new Exception($"Не смог получить серивс {nameof(ITemplateService)} или {nameof(INextRunService)} или {nameof(IJobGroupService)}");
await HandlerAsync(templateService, nextRunService, jobGroupService);
}
}, workerSettings.RepeatEvery);
}
/// <summary>
/// Рассчет следующей даты срабатываения
/// </summary>
/// <returns></returns>
private async Task HandlerAsync(ITemplateService templateService, INextRunService nextRunService, IJobGroupService jobGroupService)
{
logger.LogInformation("Начинаю обновлять NextRun по расписанию");
//// обновляем для групп у которых не включено автораспределение
//await UpdateNextRunWithEsppScheduleAsync(templateService, nextRunService, jobGroupService);
//// для групп у которых включено автораспределение
//await UpdateNextRunWithAutodistributeScheduleAsync(templateService, nextRunService, jobGroupService);
await UpdateNextRunAsync(templateService, nextRunService, jobGroupService);
logger.LogInformation($"Завершено обновление полей NextRun.");
}
private async Task UpdateNextRunAsync(ITemplateService templateService, INextRunService nextRunService, IJobGroupService jobGroupService)
{
// выбираем все шаблоны с просроченным nextRun в статусе Used
var templatesForUpdate = await templateService.Get()
.Where(t =>
t.StatusTypeId == TemplateStatusTypeEnum.Used
&& t.NextRun < DateTimeOffset.UtcNow
).ToListAsync();
logger.LogInformation("Найдено шаблонов в статусе Used с просроченным NextRun {count} шт.", templatesForUpdate.Count);
if (!templatesForUpdate.Any())
return;
foreach (var template in templatesForUpdate)
{
var newNextRun = await nextRunService.GetNextRunForTemplateAsync(template.Id, false);
template.LastRun = template.NextRun;
template.NextRun = newNextRun;
}
if (await templateService.CommitAsync(new HistoryInitiator { InitiatorComment = "Обновлён NextRun", InitiatorParrComponentId = ParrComponentsEnum.NextRun }))
{
logger.LogInformation("Обновлены значения полей NextRun для шаблонов в статусе Used, {count} шт.", templatesForUpdate.Count);
}
else
{
logger.LogError("Ошибка при обновлении значений полей NextRun, для шаблонов в статусе Used, {count} шт.", templatesForUpdate.Count);
}
}
#region old
/// <summary>
/// Обновить nextRun для ВСЕХ шаблонов, для групп у которых расписание ЕСПП (выключено автораспределение)
/// </summary>
/// <returns></returns>
private async Task UpdateNextRunWithEsppScheduleAsync(ITemplateService templateService, INextRunService nextRunService, IJobGroupService jobGroupService)
{
// выбираем шаблоны которые не учавствуют в автораспределении
// и у которых Used
// обновляем для всех шаблонов, у которых nextRun!=рассчитанному
var templatesForUpdate = await templateService.Get()
.Where(t =>
t.StatusTypeId == TemplateStatusTypeEnum.Used
&& t.Job!.Group!.IsAutoDistributionEnabled == false
&& t.NextRun < DateTimeOffset.UtcNow
).ToListAsync();
logger.LogInformation("Найдено шаблонов с выключенным автораспределением, с просроченным NextRun {count} шт.", templatesForUpdate.Count);
if (!templatesForUpdate.Any())
return;
foreach (var template in templatesForUpdate)
{
var newNextRun = await nextRunService.GetNextRunForTemplateAsync(template.Id, false);
template.LastRun = template.NextRun;
template.NextRun = newNextRun;
}
if (await templateService.CommitAsync(new HistoryInitiator { InitiatorComment = "Обновлён NextRun", InitiatorParrComponentId = ParrComponentsEnum.NextRun }))
{
logger.LogInformation("Обновлены значения ПРОСРОЧЕННЫХ полей NextRun для шаблонов с ВЫКЛЮЧЕННЫМ автораспределением, {count} шт.", templatesForUpdate.Count);
}
else
{
logger.LogError("Ошибка при обновлении ПРОСРОЧЕННЫХ значений полей NextRun, для шаблонов {count} шт., с ВЫКЛЮЧЕННЫМ автораспределением", templatesForUpdate.Count);
}
//// выбираем шаблоны которые не учавствуют в автораспределении
//// и у которых Used
//// затем группируем по GroupId, так как nextRun и расписание настраивается для группы, то для всех дочерних шаблонов, nextRun будет одинаковым
//// обновляем для всех шаблонов, у которых nextRun!=рассчитанному
//var groups = await jobGroupService.Get()
// .Where(t => t.IsAutoDistributionEnabled == false)
// .Select(t => new { t.Id, t.ReferenceDate })
// .ToListAsync();
//logger.LogInformation("Найдено {GroupCount} групп с выключенным автораспределением для обработки.", groups.Count);
//foreach (var group in groups)
//{
// //получаем по каждой группе следующий nextRun и сравниваем с существующим, если не равны, то обновляем
// //var nextRun = await esppScheduleTransformService.GetNextDateAsync(group.Id, group.ReferenceDate);
// var nextRun = await nextRunService.GetNextRunForJobGroupWithEsppSchedulleAsync(group.Id);
// // Загружаем только шаблоны текущей группы где nextRun в БД не равен расчетному
// var templatesToUpdate = await templateService.Get()
// .Where(t => t.StatusTypeId == TemplateStatusTypeEnum.Used && t.Job!.GroupId == group.Id && t.NextRun != nextRun)
// .ToListAsync();
// logger.LogInformation("Для группы {groupId}, шаблонов для обновления где nextRun!=рассчетному {newNextRun} найдено {count} шт.", group.Id, nextRun, templatesToUpdate.Count);
// if (!templatesToUpdate.Any())
// continue;
// // Обновляем
// foreach (var template in templatesToUpdate)
// {
// template.LastRun = template.NextRun;
// template.NextRun = nextRun;
// }
// // Коммитим изменения для этой группы
// if (await templateService.CommitAsync(new HistoryInitiator { InitiatorComment = "Обновлён NextRun", InitiatorParrComponentId = ParrComponentsEnum.NextRun }))
// logger.LogInformation($"Обновлены значения полей NextRun для шаблонов группы: {group.Id} с выключенным автораспределением, " +
// $"refDate: {group.ReferenceDate}. Обновлен nextRun: {nextRun} для шаблонов {templatesToUpdate.Count} шт.");
// else
// {
// logger.LogError($"Ошибка при обновлении значений полей NextRun: {nextRun}, для шаблонов {templatesToUpdate.Count} шт., группы {group.Id} с выключенным автораспределением, refDate: {group.ReferenceDate} ");
// }
//}
}
/// <summary>
/// Обновить ПРОСРОЧЕННЫЕ NextRun для групп у которых включено автораспределение
/// </summary>
/// <param name="templateService"></param>
/// <param name="nextRunService"></param>
/// <param name="jobGroupService"></param>
/// <returns></returns>
private async Task UpdateNextRunWithAutodistributeScheduleAsync(ITemplateService templateService, INextRunService nextRunService, IJobGroupService jobGroupService)
{
// получаем список всех шаблонов с включенным автораспределением у которых ПРОСРОЧЕН nextRun и они Used
// обновляем у них NextRun
var templatesForUpdate = await templateService.Get()
.Where(t => t.StatusTypeId == TemplateStatusTypeEnum.Used && t.Job.Group.IsAutoDistributionEnabled == true && t.NextRun < DateTimeOffset.UtcNow)
.ToListAsync();
logger.LogInformation("Найдено шаблонов с автораспределением, с просроченным NextRun {count} шт.", templatesForUpdate.Count);
if (!templatesForUpdate.Any())
return;
foreach (var template in templatesForUpdate)
{
var newNextRun = await nextRunService.GetNextRunForTemplateAsync(template.Id, false);
template.LastRun = template.NextRun;
template.NextRun = newNextRun;
}
if (await templateService.CommitAsync(new HistoryInitiator { InitiatorComment = "Обновлён NextRun", InitiatorParrComponentId = ParrComponentsEnum.NextRun }))
{
logger.LogInformation("Обновлены значения ПРОСРОЧЕННЫХ полей NextRun для шаблонов с ВКЛЮЧЕННЫМ автораспределением, {count} шт.", templatesForUpdate.Count);
}
else
{
logger.LogError("Ошибка при обновлении ПРОСРОЧЕННЫХ значений полей NextRun, для шаблонов {count} шт., с ВКЛЮЧЕННЫМ автораспределением", templatesForUpdate.Count);
}
}
#endregion
}
}