2023-10-05 12:28:31 +10:00
using Microsoft.EntityFrameworkCore ;
using Microsoft.Extensions.Logging ;
2026-04-30 10:35:31 +10:00
using PARR.Core.Repositories.Interfaces ;
2023-10-05 12:28:31 +10:00
using PARR.DAL.Context ;
2026-04-14 09:56:31 +10:00
using PARR.DAL.Repositories.Base ;
2026-04-30 10:35:31 +10:00
using PARR.Domain.Entities ;
2026-04-13 16:58:30 +10:00
using PARR.Domain.Enums ;
2023-10-05 12:28:31 +10:00
2026-04-30 10:35:31 +10:00
namespace PARR.DAL.Repositories
2023-10-05 12:28:31 +10:00
{
2026-04-30 10:35:31 +10:00
internal class RobotConfigurationRepository : BaseRepository < RobotConfiguration > , IRobotConfigurationRepository
2023-10-05 12:28:31 +10:00
{
2026-04-30 10:35:31 +10:00
public RobotConfigurationRepository ( DataContext dataContext , ILogger < RobotConfigurationRepository > logger ) : base ( logger , dataContext ) { }
2023-10-05 16:56:02 +10:00
2025-12-09 12:20:27 +10:00
public void ChangeTaskStatus ( TaskStatusEnum taskStatus , RobotConfiguration configuration )
2023-10-05 16:56:02 +10:00
{
configuration . TaskStatusCode = ( int ) taskStatus ;
switch ( taskStatus )
{
case TaskStatusEnum . Creating :
2025-12-09 12:20:27 +10:00
ChangeRobotStatus ( RobotStatusEnum . Wait , configuration ) ;
2023-10-05 16:56:02 +10:00
break ;
case TaskStatusEnum . Updating :
2025-12-09 12:20:27 +10:00
ChangeRobotStatus ( RobotStatusEnum . Wait , configuration ) ;
2023-10-05 16:56:02 +10:00
break ;
case TaskStatusEnum . Ok :
2025-12-09 12:20:27 +10:00
ChangeRobotStatus ( RobotStatusEnum . Complete , configuration ) ;
2023-10-05 16:56:02 +10:00
break ;
default :
break ;
}
2026-03-06 15:10:30 +10:00
}
2023-10-05 16:56:02 +10:00
2026-03-06 15:10:30 +10:00
public bool SetUpdateTaskStatusIfAllow ( RobotConfiguration configuration )
{
var updatingStatus = TaskStatusEnum . Updating ;
// ставить статус Updating можно только если текущий статус == Ok
if ( configuration . TaskStatusCode ! = ( int ) TaskStatusEnum . Ok )
{
2026-03-18 17:51:54 +10:00
int taskStatusValue = configuration . TaskStatusCode ;
string taskStatusName = Enum . IsDefined ( typeof ( TaskStatusEnum ) , taskStatusValue )
? ( ( TaskStatusEnum ) taskStatusValue ) . ToString ( )
: $"Unknown ({taskStatusValue})" ;
2026-03-11 12:10:11 +10:00
logger . LogInformation ( "Нельзя установить статус {newStatus} для конфигурации {configurationId}, templateId: {templateId}, так как текущий статус {currentStatus}" ,
2026-03-27 11:58:03 +10:00
updatingStatus , configuration . Id , configuration . TemplateId , taskStatusName ) ;
2026-03-06 15:10:30 +10:00
return false ;
}
2026-03-13 10:22:13 +10:00
// Если хотим поставить Updating у шаблона, можно ставить только в том случае, если у шаблона уже есть ScheduleEsppId
if ( configuration . RobotCode = = ( int ) RobotsEnum . TemplateOrder )
{
// есть ли связь у config с templetes, может инклуда нет, мало ли
if ( configuration . Template = = null )
{
logger . LogWarning ( "При изменении статуса задания на обновление шаблона, не смог проверить наличае ScheduleEsppId, так как нет Include с Templates. Пропустил эту проверку. configurationId: {configurationId}" , configuration . Id ) ;
}
else
{
if ( configuration . Template . ScheduleEsppId = = null )
{
logger . LogInformation ( "Нельзя установить статус {newStatus} для конфигурации {configurationId}, templateId: {templateId}, так как у шаблона отсутсвтует ScheduleEsppId=null" ,
updatingStatus , configuration . Id , configuration . TemplateId ) ;
return false ;
}
}
}
2026-03-06 15:10:30 +10:00
// Статус О К , можно ставить Updating
ChangeTaskStatus ( updatingStatus , configuration ) ;
2026-03-11 12:10:11 +10:00
logger . LogInformation ( "Установлен статус {newStatus} для конфигурации {configurationId}, templateId: {templateId}" , updatingStatus , configuration . Id , configuration . TemplateId ) ;
2026-03-06 15:10:30 +10:00
return true ;
2023-10-05 16:56:02 +10:00
}
2026-03-06 15:10:30 +10:00
2025-12-09 12:20:27 +10:00
public void ChangeRobotStatus ( RobotStatusEnum robotStatus , RobotConfiguration configuration )
2023-10-05 16:56:02 +10:00
{
configuration . RobotStatusCode = ( int ) robotStatus ;
switch ( robotStatus )
{
case RobotStatusEnum . InProgress :
configuration . AttemptsNumber + + ;
2023-10-06 11:38:33 +10:00
configuration . LastRobotStatusUpdated = DateTimeOffset . UtcNow ;
2023-10-05 16:56:02 +10:00
break ;
//case RobotStatusEnum.Error:
// break;
case RobotStatusEnum . Complete :
2023-10-06 11:38:33 +10:00
configuration . LastRobotStatusUpdated = DateTimeOffset . UtcNow ;
2023-10-05 16:56:02 +10:00
break ;
case RobotStatusEnum . Wait :
2023-10-06 11:38:33 +10:00
configuration . LastRobotStatusUpdated = null ;
2023-10-05 16:56:02 +10:00
configuration . AttemptsNumber = 0 ;
break ;
default :
break ;
}
}
2026-05-25 16:59:42 +10:00
public async Task < bool > SetInProgressStatusAsync ( Guid id )
{
// Если задание все еще в статусе Wait (RobotStatusEnum.Wait), установить ему статус "InProgress"
// Выполняем атомарный UPDATE напрямую в базе данных
var affectedRows = await EntitySet . Where ( t = > t . Id = = id & & t . RobotStatusCode = = ( int ) RobotStatusEnum . Wait )
. ExecuteUpdateAsync ( s = > s
. SetProperty ( t = > t . RobotStatusCode , ( int ) RobotStatusEnum . InProgress )
. SetProperty ( t = > t . LastRobotStatusUpdated , DateTimeOffset . UtcNow )
) ;
return affectedRows > 0 ;
}
2025-11-26 14:34:03 +10:00
public RobotConfiguration GetFromTemplateByRobotCode ( RobotsEnum robotsEnum , Template template )
2023-10-05 16:56:02 +10:00
{
var config = template . RobotConfigurations . FirstOrDefault ( t = > t . RobotCode = = ( int ) robotsEnum ) ;
if ( config = = null )
{
logger . LogError ( $"У шаблона нет конфигурации роботов. TemplateId: {template.Id}" ) ;
throw new Exception ( $"У шаблона нет конфигурации роботов. TemplateId: {template.Id}" ) ;
}
return config ;
}
// Поиск невыполненных заданий и установка им статуса ошибки робота
2026-05-25 16:59:42 +10:00
public async Task MarkExpiredTasksAsFailedAsync ( int robotAttemptsNumber , TimeSpan robotWaitTime )
2023-10-05 16:56:02 +10:00
{
//Ищем `RobotStatusCode` = 22 и `LastStatusUpdated` истекло и `AttemptsNumber` >= допустимого значения из настроек,
//ставим всем этим записям `RobotStatusCode`= 33
var endDate = DateTimeOffset . UtcNow . Add ( - robotWaitTime ) ;
var configObjs = await EntitySet . Where ( t = >
t . RobotStatusCode = = ( int ) RobotStatusEnum . InProgress
& & t . AttemptsNumber > = robotAttemptsNumber
2023-10-06 11:38:33 +10:00
& & t . LastRobotStatusUpdated < = endDate
2023-10-05 16:56:02 +10:00
) . ToListAsync ( ) ;
if ( ! configObjs . Any ( ) )
return ;
configObjs . ForEach ( item = >
{
2025-12-09 12:20:27 +10:00
ChangeRobotStatus ( RobotStatusEnum . Error , item ) ;
2023-10-05 16:56:02 +10:00
logger . LogInformation ( $"Устанавливаю RobotStatus: {RobotStatusEnum.Error} для RobotConfigurationId {item.Id}" ) ;
} ) ;
var result = await CommitAsync ( ) ;
if ( ! result )
logger . LogError ( $"Ошибка при сохранении изменений RobotStatus для RobotConfigurationId: item.Id, RobotStatus: {RobotStatusEnum.Error}" ) ;
}
2023-10-05 12:28:31 +10:00
}
}