diff --git a/PARR.API/Controllers/V1/RobotTaskController.cs b/PARR.API/Controllers/V1/RobotTaskController.cs index 53af1697..5b70ca35 100644 --- a/PARR.API/Controllers/V1/RobotTaskController.cs +++ b/PARR.API/Controllers/V1/RobotTaskController.cs @@ -7,6 +7,7 @@ using PARR.API.Contracts.V1.Responses; using PARR.API.Contracts.V1.Responses.Base; using PARR.API.Controllers.V1.Base; using PARR.API.Services.Interfaces; +using PARR.API.Settings; using PARR.Core.Services.RobotTask.Interfaces; using PARR.Domain.Common.Roles; using PARR.Domain.Entities.Base.History; @@ -18,38 +19,22 @@ namespace PARR.API.Controllers.V1 [Authorize(Roles = ParrRoles.EsppRobot.RoleOrAdmin)] public class RobotTaskController : BaseApiController { - private readonly IRobotTaskService robotTaskService; - - private readonly IMapper mapper; - //private readonly SettingsFromDb settingsFromDb; - //private readonly IRobotConfigurationRepository robotConfigurationService; - //private readonly ILogger logger; - private readonly IClientService clientService; - //private readonly IRobotHistoryRepository robotHistoryService; - //private readonly IShortcodesService shortcodesService; - //private readonly INextRunService nextRunService; + private readonly IRobotTaskService _robotTaskService; + private readonly CommonSettings _commonSettings; + private readonly IMapper _mapper; + private readonly IClientService _clientService; public RobotTaskController( IMapper mapper, - //SettingsFromDb settingsFromDb, - //IRobotConfigurationRepository robotConfigurationService, - //ILogger logger, IClientService clientService, - //IRobotHistoryRepository robotHistoryService, - //IShortcodesService shortcodesService, - //INextRunService nextRunService - IRobotTaskService robotTaskService + IRobotTaskService robotTaskService, + CommonSettings commonSettings ) { - this.robotTaskService = robotTaskService; - this.mapper = mapper; - //this.settingsFromDb = settingsFromDb; - //this.robotConfigurationService = robotConfigurationService; - //this.logger = logger; - this.clientService = clientService; - //this.robotHistoryService = robotHistoryService; - //this.shortcodesService = shortcodesService; - //this.nextRunService = nextRunService; + _robotTaskService = robotTaskService; + _commonSettings = commonSettings; + _mapper = mapper; + _clientService = clientService; } @@ -66,314 +51,37 @@ namespace PARR.API.Controllers.V1 switch (robotCode) { case RobotsEnum.TemplateOrder: - var templateTask = await robotTaskService.GetTemplateTaskAsync( + var templateTask = await _robotTaskService.GetTemplateTaskAsync( taskStatusCode, requestQuery.SetInProgressStatus ?? false, - clientService.GetClientIp()?.ToString(), + _clientService.GetClientIp()?.ToString(), requestQuery.RobotId ); - var templateResponse = mapper.Map(templateTask); + var templateResponse = _mapper.Map(templateTask); return Ok(new Response(templateResponse, true)); case RobotsEnum.ScheduleOrder: var historyIniciator = new HistoryInitiator { - InitiatorComment="Задание роботу, расписание.", - InitiatorIp=clientService.GetClientIp()?.ToString(), - InitiatorParrComponentId= ParrComponentsEnum.Api + InitiatorComment = "Задание роботу, расписание.", + InitiatorIp = _clientService.GetClientIp()?.ToString(), + InitiatorParrComponentId = ParrComponentsEnum.Api }; - var scheduleTask = await robotTaskService.GetScheduleTaskAsync( + var scheduleTask = await _robotTaskService.GetScheduleTaskAsync( taskStatusCode, requestQuery.SetInProgressStatus ?? false, historyIniciator.InitiatorIp, requestQuery.RobotId, - historyIniciator + historyIniciator, + _commonSettings.ScheduleCooldownDuration ); - var scheduleResponse = mapper.Map(scheduleTask); + var scheduleResponse = _mapper.Map(scheduleTask); return Ok(new Response(scheduleResponse, true)); default: throw new AppValidationException("Некорректное значение robotCode"); } } - - - #region Old - - // /// - // /// Получить задание для робота по коду робота и по статусу задания - // /// - // /// - // /// - // /// - // [HttpGet(ApiRoutes.RobotTask.GetByRobotAndStatusTask)] - // public async Task GetByRobotAndStatusTask([FromRoute] RobotsEnum robotCode, [FromRoute] TaskStatusEnum taskStatusCode, [FromQuery] RobotTaskQuery requestQuery) - // { - // //Ищем все задания с превышенным кол-вом попыток и с просроченным временем и ставим им статус ошибки - // await robotConfigurationService.MarkExpiredTasksAsFailedAsync(settingsFromDb.RobotAttemptsNumber, settingsFromDb.RobotWaitTime); - - - // var query = robotConfigurationService.Get() - // .AsSingleQuery() - // .Where(t => t.RobotCode == (int)robotCode && t.TaskStatusCode == (int)taskStatusCode); - - // switch (robotCode) - // { - // case RobotsEnum.TemplateOrder: - // // шаблоны - // query = query - // .Include(t => t.Template) - // .ThenInclude(t => t!.Unit) - // .ThenInclude(t => t!.UnitValues) - // .ThenInclude(t => t.Field) - // .Include(t => t.Template) - // .ThenInclude(t => t!.Unit) - // .ThenInclude(t => t!.UnitValues) - // .ThenInclude(t => t.Value) - // .Include(t => t.Template) - // .ThenInclude(a => a!.Job) - // .ThenInclude(t => t!.Group) - // .ThenInclude(g => g.GroupType) - // .Include(t => t.Template) - // .ThenInclude(w => w!.Job) - // .ThenInclude(t => t!.Tnk) - // .ThenInclude(s => s!.Subprocess) - // .ThenInclude(p => p!.Process); - - // query = query - // .Include(t => t.Template) - // .ThenInclude(t => t!.UnitsInTemplate); - - // break; - - // case RobotsEnum.ScheduleOrder: - // //расписание - // query = query - // .Include(t => t.Template) - // .ThenInclude(t => t!.Unit) - // .ThenInclude(t => t!.UnitValues) - // .ThenInclude(t => t.Field) - // .Include(t => t.Template) - // .ThenInclude(t => t!.Unit) - // .ThenInclude(t => t!.UnitValues) - // .ThenInclude(t => t.Value) - // .Include(t => t.Template) - // .ThenInclude(a => a!.Job) - // .ThenInclude(t => t!.Group) - // .ThenInclude(g => g.GroupType) - // .Include(t => t.Template) - // .ThenInclude(a => a!.Job) - // .ThenInclude(t => t!.Group) - // .ThenInclude(t => t!.EsppSchValues) - // .ThenInclude(t => t!.EsppSchTypeConfig) - // .ThenInclude(t => t!.EsppSchTypeSchedule) - // .Include(t => t.Template) - // .ThenInclude(t => t!.Job) - // .ThenInclude(t => t!.Group) - // .ThenInclude(t => t!.ScheduleExcludeType) - // .Include(t => t.Template) - // .ThenInclude(t => t!.Job) - // .ThenInclude(t => t!.Group) - // .ThenInclude(t => t.ScheduleExcludeTypeCalendar) - // .Include(t => t.Template) - // .ThenInclude(t => t!.Job) - // .ThenInclude(t => t!.Tnk) - // .Include(t => t.Template) - // .ThenInclude(t => t!.UnitsInTemplate); - - // //выбираем только записи с созданными шаблонами (у которых статус 20 или 30), а только потом у них ищем расписания - // var createdTemplates = robotConfigurationService.Get() - // .Where(t => t.RobotCode == (int)RobotsEnum.TemplateOrder && (t.TaskStatusCode == (int)TaskStatusEnum.Ok)) - // .Select(t => t.TemplateId); - // query = query.Where(t => t.RobotCode == (int)RobotsEnum.ScheduleOrder && createdTemplates.Contains(t.TemplateId)); - // // query = query.Where(t => t.RobotCode == (int)RobotsEnum.ScheduleOrder && t.TemplateId==Guid.Parse("7cb7c3be-506d-40e0-a63f-4554edb52459")); - // break; - - // default: - // break; - // } - - - // // сортируем по NextRun, чтобы те у которых дата след срабатывания ближе к текущей, выполнились скорее - // query = query.OrderBy(t => t.Template!.NextRun).ThenBy(t => t.Template!.IsActiveSchedule).ThenBy(t => t.Template.IsActiveTemplate); - - // RobotConfiguration? task = null; - - // //ищем задание в ожидании, если нашли, выбираем его - // task = await query.FirstOrDefaultAsync(t => t.RobotStatusCode == (int)RobotStatusEnum.Wait); - - // if (task == null) - // { - // //ищем задания в работе, которые можно перезапустить - // //Поиск по `RobotStatusCode` = 22. - // //Далее проверяется `LastStatusUpdated`, что время последнего смены статуса не превышает допустимого(берется из настроек, поле `RobotWaitTime`) - // //и что текущая попытка не больше разрешенной(берется из настроек, поле `RobotAttemptsNumber`) - если это так, берется эта запись. - - // var endDate = DateTimeOffset.UtcNow.Add(-settingsFromDb.RobotWaitTime); - // task = await query - // .FirstOrDefaultAsync(t => - // t.RobotStatusCode == (int)RobotStatusEnum.InProgress - // && t.AttemptsNumber < settingsFromDb.RobotAttemptsNumber - // && t.LastRobotStatusUpdated < endDate - // ); - // } - - // if (task == null) - // return NotFound(); - - // if (requestQuery?.SetInProgressStatus == true) - // { - // var resultSetStatus = await SetInProgressStatusAsync(task.Id); - // if (resultSetStatus == false) - // { - // logger.LogError($"Ошибка при установке статуса {RobotStatusEnum.InProgress.ToString()} для задания RobotConfigutationId {task.Id} (при выдаче задания роботу)"); - // return BadRequest(new Response(false, new List { new ErrorModel { Message = "Ошибка при выдаче задания." } })); - // } - // } - - // switch (robotCode) - // { - // case RobotsEnum.TemplateOrder: - // { //RobotTaskTemplateResponse - // var robotTaskTemplateResponse = mapper.Map(task); - - // robotTaskTemplateResponse.FullDescription = NormalizeLineEndingsToCrlf(await shortcodesService.ApplyShortcodesAsync(robotTaskTemplateResponse.FullDescription, task.Template!)); - // robotTaskTemplateResponse.ShortDescription = await shortcodesService.ApplyShortcodesAsync(robotTaskTemplateResponse.ShortDescription, task.Template!); - // robotTaskTemplateResponse.Solution = NormalizeLineEndingsToCrlf(await shortcodesService.ApplyShortcodesAsync(robotTaskTemplateResponse.Solution, task.Template!)); - // robotTaskTemplateResponse.TnkName = await shortcodesService.ApplyShortcodesAsync(robotTaskTemplateResponse.TnkName, task.Template!); - // robotTaskTemplateResponse.WorkName = await shortcodesService.ApplyShortcodesAsync(robotTaskTemplateResponse.WorkName, task.Template!); - // robotTaskTemplateResponse.WorkGroup = await shortcodesService.ApplyShortcodesAsync(robotTaskTemplateResponse.WorkGroup, task.Template!); - // robotTaskTemplateResponse.ResponseArea = await shortcodesService.ApplyShortcodesAsync(robotTaskTemplateResponse.ResponseArea, task.Template!); - - // return Ok(new Response(robotTaskTemplateResponse, true)); - // } - // case RobotsEnum.ScheduleOrder: - // { // если был запрос на расписание, проверяем у него nextRun, lastRun, обновляем их - // var resultUpdateNextRun = await UpdateNextRunAsync(task); - // if (!resultUpdateNextRun) - // { - // logger.LogError("Ошибка при расчете NextRun для templateId: {templateId}", task.TemplateId); - // return BadRequest(new Response(false, new List { new ErrorModel { Message = "Ошибка при расчете NextRun" } })); - // } - - // //RobotTaskScheduleResponse - // var robotTaskScheduleResponse = mapper.Map(task); - - // robotTaskScheduleResponse.Timezone = settingsFromDb.EsppScheduleTimezone; - - // robotTaskScheduleResponse.WorkGroup = await shortcodesService.ApplyShortcodesAsync(robotTaskScheduleResponse.WorkGroup, task.Template!); - // robotTaskScheduleResponse.ResponseArea = await shortcodesService.ApplyShortcodesAsync(robotTaskScheduleResponse.ResponseArea, task.Template!); - - // //var nextRunWithRobotTz = nextRunService.GetNextRunWithTimezoneEsppAndResponseArea(task.Template!.NextRun, task.Template!.Job?.Group?.IsResponseAreaTimezone, robotTaskScheduleResponse.ResponseArea); - // //nextRun в часовой зоне УЗ Робота ЕСПП - // var nextRunWithRobotTz = task.Template!.NextRun.Add(nextRunService.GetEsppAccountOffset()); - - // //на всякий случай еще раз проверяем, что дата не устарела и отправляем задание - // if (nextRunWithRobotTz < DateTimeOffset.UtcNow) - // { - // logger.LogError("Ошибка при расчете NextRun для templateId: {templateId}, итоговое значение для робота, меньше чем сейчас {nextRunWithRobotTz}<{now}", - // task.TemplateId, nextRunWithRobotTz, DateTimeOffset.UtcNow); - // return BadRequest(new Response(false, new List { new ErrorModel { Message = "Ошибка при расчете NextRun" } })); - // } - - // robotTaskScheduleResponse.NextStart = EsppScheduleHelpers.GetNextRun(nextRunWithRobotTz); - // robotTaskScheduleResponse.GenerationTime = EsppScheduleHelpers.GetGenerationTime(nextRunWithRobotTz); - - // return Ok(new Response(robotTaskScheduleResponse, true)); - // } - // default: - // break; - // } - - // return BadRequest(); - // } - - - // /// - // /// Обоновить NextRun если он устарел - // /// - // /// - // /// - // private async Task UpdateNextRunAsync(RobotConfiguration task) - // { - // var template = task.Template!; - - // //var nextRun = await esppScheduleTransformService.GetNextDateAsync(template.Job!.GroupId, template!.Job!.Group!.ReferenceDate); - // var nextRun = await nextRunService.GetNextRunForTemplateAsync(template.Id, false); - - // if (!nextRun.HasValue) - // { - // logger.LogError("При обновлении nextRun для шаблона {templateId}, расчитанный nextRun=null, ошибка в расчетах.", template.Id); - // return false; - // } - - // if (nextRun.Value < DateTimeOffset.UtcNow) - // { - // logger.LogError("При обновлении nextRun для шаблона {templateId}, расчитанный nextRun - // /// Устанавливаем статус "Робот взял в работу", пишем в историю работы роботов инф о начале работ - // /// - // /// - // /// - // private async Task SetInProgressStatusAsync(Guid taskId) - // { - // var config = await robotConfigurationService.GetAsync(taskId); - - // //изменение статуса робота - // robotConfigurationService.ChangeRobotStatus(RobotStatusEnum.InProgress, config!); - - // if (!await robotConfigurationService.CommitAsync()) - // return false; - - // //записываем в лог робота - // var history = new RobotHistory - // { - // Id = Guid.NewGuid(), - // HistoryLevel = (int)RobotHistoryLevelEnum.Start, - // TaskStatusCode = config.TaskStatusCode, - // RobotConfigurationId = config.Id, - // RobotIp = clientService.GetClientIp()?.ToString() - // }; - - // if (!await robotHistoryService.CreateAsync(history) || !await robotHistoryService.CommitAsync()) - // return false; - - // return true; - // } - - - // /// - // /// Приводит переносы строк в тексте к формату CRLF (\r\n) - // /// - // /// Исходный текст - // /// Текст с унифицированными переносами строк - // private string NormalizeLineEndingsToCrlf(string? text) - // { - // if (string.IsNullOrEmpty(text)) - // return string.Empty; - - // // Заменяем любые варианты переносов (\r\n, \r, \n) на единый \r\n - // return System.Text.RegularExpressions.Regex.Replace(text, @"\r\n|\r|\n", "\r\n"); - // } - - #endregion } } diff --git a/PARR.API/Installers/SettingsInstaller.cs b/PARR.API/Installers/SettingsInstaller.cs index 4ea53e8f..5384ebf8 100644 --- a/PARR.API/Installers/SettingsInstaller.cs +++ b/PARR.API/Installers/SettingsInstaller.cs @@ -23,6 +23,10 @@ namespace PARR.API.Installers configuration.GetSection(nameof(MonitoringSettings)).Bind(monitoringSettings); services.AddSingleton(monitoringSettings); + var commonSettings = new CommonSettings(); + configuration.GetSection(nameof(CommonSettings)).Bind(commonSettings); + services.AddSingleton(commonSettings); + //TODO: add other } } diff --git a/PARR.API/Settings/CommonSettings.cs b/PARR.API/Settings/CommonSettings.cs new file mode 100644 index 00000000..e990f285 --- /dev/null +++ b/PARR.API/Settings/CommonSettings.cs @@ -0,0 +1,15 @@ +namespace PARR.API.Settings +{ + /// + /// Общие настройки API + /// + public record CommonSettings + { + /// + /// Период охлаждения (кулдаун) для расписаний. + /// Запрещает повторно брать активные шаблоны в работу, если с момента их последнего запуска прошло меньше этого времени. + /// Применяется только для инициаторов EsppScheduleSync и NextRun. + /// + public TimeSpan ScheduleCooldownDuration { get; init; } = TimeSpan.Zero; + } +} diff --git a/PARR.API/appsettings.json b/PARR.API/appsettings.json index cbb8bc08..1d9e827e 100644 --- a/PARR.API/appsettings.json +++ b/PARR.API/appsettings.json @@ -113,5 +113,8 @@ "RabbitMq": { "ThresholdConnections": 33 } + }, + "CommonSettings": { + "ScheduleCooldownDuration": "03:00:00" } } diff --git a/PARR.Core/Services/RobotTask/Implementations/RobotTaskService.cs b/PARR.Core/Services/RobotTask/Implementations/RobotTaskService.cs index 3d41f915..87155e01 100644 --- a/PARR.Core/Services/RobotTask/Implementations/RobotTaskService.cs +++ b/PARR.Core/Services/RobotTask/Implementations/RobotTaskService.cs @@ -52,7 +52,7 @@ namespace PARR.Core.Services.RobotTask.Implementations public async Task GetTemplateTaskAsync(TaskStatusEnum taskStatusCode, bool acquireTask, string? robotIp, string? robotId) { - var templateTask = await GetTaskAsync(RobotsEnum.TemplateOrder, taskStatusCode, acquireTask, robotIp, robotId); + var templateTask = await GetTaskAsync(RobotsEnum.TemplateOrder, taskStatusCode, acquireTask, robotIp, robotId, TimeSpan.Zero); var task = mapper.Map(templateTask); @@ -72,9 +72,9 @@ namespace PARR.Core.Services.RobotTask.Implementations } - public async Task GetScheduleTaskAsync(TaskStatusEnum taskStatusCode, bool acquireTask, string? robotIp, string? robotId, IHistoryInitiator historyInitiator) + public async Task GetScheduleTaskAsync(TaskStatusEnum taskStatusCode, bool acquireTask, string? robotIp, string? robotId, IHistoryInitiator historyInitiator, TimeSpan scheduleCooldownDuration) { - var scheduleTask = await GetTaskAsync(RobotsEnum.ScheduleOrder, taskStatusCode, acquireTask, robotIp, robotId); + var scheduleTask = await GetTaskAsync(RobotsEnum.ScheduleOrder, taskStatusCode, acquireTask, robotIp, robotId, scheduleCooldownDuration); // Проверяем nextRun, lastRun, обновляем их @@ -121,14 +121,14 @@ namespace PARR.Core.Services.RobotTask.Implementations /// /// /// - private async Task GetTaskAsync(RobotsEnum robotCode, TaskStatusEnum taskStatusCode, bool acquireTask, string? robotIp, string? robotId) + private async Task GetTaskAsync(RobotsEnum robotCode, TaskStatusEnum taskStatusCode, bool acquireTask, string? robotIp, string? robotId, TimeSpan scheduleCooldownDuration) { // 1. Ищем все задания с превышенным кол-вом попыток и просроченным временем, ставим им статус ошибки await robotConfigurationRepository.MarkExpiredTasksAsFailedAsync(settingsFromDb.RobotAttemptsNumber, settingsFromDb.RobotWaitTime); // 2. Ищем доступные задания - var availableTasks = await GetAvailableTasksAsync(robotCode, taskStatusCode); + var availableTasks = await GetAvailableTasksAsync(robotCode, taskStatusCode, scheduleCooldownDuration); if (availableTasks.Count == 0) throw new NotFoundException("Нет доступных заданий для робота"); @@ -137,7 +137,7 @@ namespace PARR.Core.Services.RobotTask.Implementations if (acquireTask) { - // Берем задание в работу, устанавливаем ей статус "В работе" + // Берем задание в работу, устанавливаем ему статус "В работе" acquiredTaskId = await AcquireTaskAsync(availableTasks, robotIp, robotId); if (acquiredTaskId == null) @@ -165,21 +165,35 @@ namespace PARR.Core.Services.RobotTask.Implementations /// /// /// - private async Task> GetAvailableTasksAsync(RobotsEnum robotCode, TaskStatusEnum taskStatusCode) + private async Task> GetAvailableTasksAsync(RobotsEnum robotCode, TaskStatusEnum taskStatusCode, TimeSpan scheduleCooldownDuration) { var query = robotConfigurationRepository.Get() .AsNoTracking() - .Where(t => t.RobotCode == (int)robotCode && t.TaskStatusCode == (int)taskStatusCode); + .Where(t => t.RobotCode == (int)robotCode/* && t.TaskStatusCode == (int)taskStatusCode*/); // Если это задание для робота расписаний if (robotCode == RobotsEnum.ScheduleOrder) { // Выбираем только записи с созданными шаблонами (у которых статус 30), а только потом ищем у них расписания - var createdTemplates = robotConfigurationRepository.Get() - .Where(t => t.RobotCode == (int)RobotsEnum.TemplateOrder && t.TaskStatusCode == (int)TaskStatusEnum.Ok) - .Select(t => t.TemplateId); + #region Старый не оптимизированный запрос + //var createdTemplates = robotConfigurationRepository.Get() + // .Where(t => t.RobotCode == (int)RobotsEnum.TemplateOrder && t.TaskStatusCode == (int)TaskStatusEnum.Ok) + // .Select(t => t.TemplateId); + //query = query.Where(t => createdTemplates.Contains(t.TemplateId)); + #endregion + query = query.Where(t => t.Template!.RobotConfigurations.Any(x => x.RobotCode == (int)RobotsEnum.TemplateOrder && x.TaskStatusCode == (int)TaskStatusEnum.Ok)); - query = query.Where(t => createdTemplates.Contains(t.TemplateId)); + + // Не берем шаблоны, у которых lastRun + 3 часа < сейчас, и у них последний инициатор был или nextRun (10) или esppSchedule (5), это условие применяется только к активированным расписаниям + var cooldownThreshold = DateTimeOffset.UtcNow.Add(-scheduleCooldownDuration); + query = query.Where(t => + // Условие кулдауна: проверяем, попадает ли шаблон под ЗАПРЕТ + !( + t.Template!.IsActiveSchedule + && (t.Template.InitiatorParrComponentId == ParrComponentsEnum.EsppScheduleSync || t.Template.InitiatorParrComponentId == ParrComponentsEnum.NextRun) + && t.Template.LastRun >= cooldownThreshold + ) + ); } // Сортируем по nextRun, чтобы те, у кого nextRun ближе к текущей, выполнились скорее @@ -189,7 +203,14 @@ namespace PARR.Core.Services.RobotTask.Implementations var tasks = new List(); // Ещем первые 10 заданий в статусе ОЖИДАНИЕ - tasks = await query.Where(t => t.RobotStatusCode == (int)RobotStatusEnum.Wait).Take(TakeTasks).Select(t => t.Id).ToListAsync(); + tasks = await query + .Where(t => + t.RobotStatusCode == (int)RobotStatusEnum.Wait + && t.TaskStatusCode == (int)taskStatusCode + ).Take(TakeTasks) + .Select(t => t.Id) + .ToListAsync(); + logger.LogDebug("Найдено заданий в статусе 'Ожидание' {Count} шт. Робот '{Robot}'", tasks.Count, robotCode.ToString()); diff --git a/PARR.Core/Services/RobotTask/Interfaces/IRobotTaskService.cs b/PARR.Core/Services/RobotTask/Interfaces/IRobotTaskService.cs index c859ad03..1b39e844 100644 --- a/PARR.Core/Services/RobotTask/Interfaces/IRobotTaskService.cs +++ b/PARR.Core/Services/RobotTask/Interfaces/IRobotTaskService.cs @@ -29,7 +29,8 @@ namespace PARR.Core.Services.RobotTask.Interfaces /// /// /// + /// /// - Task GetScheduleTaskAsync(TaskStatusEnum taskStatusCode, bool acquireTask, string? robotIp, string? robotId, IHistoryInitiator historyInitiator); + Task GetScheduleTaskAsync(TaskStatusEnum taskStatusCode, bool acquireTask, string? robotIp, string? robotId, IHistoryInitiator historyInitiator, TimeSpan scheduleCooldownDuration); } } diff --git a/PARR.NextRun/NextRunIntervalService.cs b/PARR.NextRun/NextRunIntervalService.cs index 9c5582df..14430d7f 100644 --- a/PARR.NextRun/NextRunIntervalService.cs +++ b/PARR.NextRun/NextRunIntervalService.cs @@ -61,69 +61,5 @@ namespace PARR.NextRun }, workerSettings.RepeatEvery); } - - ///// - ///// Рассчет следующей даты срабатываения - ///// - ///// - //private async Task HandlerAsync(ITemplateService templateService, INextRunService nextRunService, IRobotConfigurationService robotConfigurationService) - //{ - // logger.LogInformation("Начинаю обновлять NextRun по расписанию"); - - // await UpdateNextRunAsync(templateService, nextRunService, robotConfigurationService); - - // logger.LogInformation($"Завершено обновление полей NextRun."); - //} - - - //private async Task UpdateNextRunAsync(ITemplateService templateService, INextRunService nextRunService, IRobotConfigurationService robotConfigurationService) - //{ - // // выбираем все шаблоны с просроченным nextRun в статусе Used - - // var templatesForUpdate = await templateService.Get() - // .Include(t => t.RobotConfigurations) - // .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); - - // if (newNextRun.HasValue) - // { - // template.LastRun = template.NextRun; - // template.NextRun = newNextRun.Value; - - // //так как nextRun обновился, пробуем поставить задание на обновление - // var config = robotConfigurationService.GetFromTemplateByRobotCode(RobotsEnum.ScheduleOrder, template); - // robotConfigurationService.SetUpdateTaskStatusIfAllow(config); - // } - // else - // { - // logger.LogError("При расчете nextRun для шаблона {templateId}, '{templateName}', nextRun=null. Это значит что при расчете возникла ошибка.", template.Id, template.Name); - // } - // } - - // 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); - // } - - //} - - - } } diff --git a/PARR.NextRun/NextRunRabbitService.cs b/PARR.NextRun/NextRunRabbitService.cs index 56df1fe2..3de62921 100644 --- a/PARR.NextRun/NextRunRabbitService.cs +++ b/PARR.NextRun/NextRunRabbitService.cs @@ -99,81 +99,5 @@ namespace PARR.NextRun } } - - ///// - ///// Обновить все NextRun в JobGroup - ///// - ///// - ///// - //private async Task UpdateNextRunAsync(NextRunUpdateMq queryMq) - //{ - // using var scope = serviceProvider.CreateScope(); - - // var templateService = scope.ServiceProvider.GetRequiredService(); - // var nextRunService = scope.ServiceProvider.GetRequiredService(); - // var robotConfigurationService = scope.ServiceProvider.GetRequiredService(); - - // // Берем шаблоны только в статусе Used - // var templates = await templateService.Get() - // .Include(t => t.RobotConfigurations) - // .Where(t => - // t.Job!.GroupId == queryMq.JobGroupId - // && t.StatusTypeId == TemplateStatusTypeEnum.Used - // ).ToListAsync(); - - // logger.LogInformation("Найдено шаблонов {count} шт. в статусе Used в группе работ {jobGroupId}", templates.Count, queryMq.JobGroupId); - - // if (!templates.Any()) - // return; - - // var updatedTemplates = 0; - - // foreach (var template in templates) - // { - // var newNextRun = await nextRunService.GetNextRunForTemplateAsync(template.Id, false); - - // if (newNextRun == null) - // { - // logger.LogError("При расчете nextRun для шаблона {templateId}, {templateName} вернулся null", template.Id, template.Name); - // continue; - // } - - // if (template.NextRun != newNextRun) - // { - // logger.LogInformation("Обновлен nextRun для шаблона {templateId}, {templateName}, newNextRun: {newNextRun}, oldNextRun: {oldNextRun}", - // template.Id, template.Name, newNextRun, template.NextRun); - - // template.LastRun = template.NextRun; - // template.NextRun = newNextRun.Value; - - // //так как nextRun обновился, пробуем поставить задание на обновление - // var config = robotConfigurationService.GetFromTemplateByRobotCode(RobotsEnum.ScheduleOrder, template); - // robotConfigurationService.SetUpdateTaskStatusIfAllow(config); - - // updatedTemplates++; - // } - // else - // { - // logger.LogDebug("Не требуется обновлять nextRun для шаблона {templateId}, {templateName}. Рассчитанный и исходный равны. NextRun: {NextRun}", - // template.Id, template.Name, template.NextRun); - // } - // } - - // if (updatedTemplates > 0) - // { - // if (await templateService.CommitAsync(queryMq.Initiator)) - // { - // logger.LogInformation("Успешно обновлены nextRun у {count} шаблонов, группа работ: {jobGroupId}", updatedTemplates, queryMq.JobGroupId); - // } - // else - // { - // logger.LogError("При сохранении nextRun для шаблонов {count} шт, произошла ошибка при сохранении в БД. JobGroupId: {jobGroupId}", updatedTemplates, queryMq.JobGroupId); - // } - // } - // else - // { - // logger.LogInformation("Для группы работ {jobGroupId}, все nextRun актуальны. Нечего обновлять.", queryMq.JobGroupId); - // } - //} } }