ExecuteRobotSubTaskCommandHandler.cs 5.57 KB
using MassTransit;
using Microsoft.Extensions.Logging;
using Rcs.Application.Common;
using Rcs.Application.Services;
using Rcs.Application.Services.Protocol;
using Rcs.Application.MessageBus.Commands;
using Rcs.Domain.Repositories;
using Rcs.Infrastructure.PathFinding.Services;
using TaskStatus = Rcs.Domain.Entities.TaskStatus;

namespace Rcs.Infrastructure.MessageBus.Handlers.Commands;

/// <summary>
/// 鎵ц瀛愪换鍔″懡浠ゅ鐞嗗櫒
/// 澶勭悊閫昏緫涓?SubTaskCompletedDomainEventHandler 涓?85 琛屽墠涓€鑷达細
/// 娓呯悊VDA璺緞缂撳瓨銆佹竻绌烘満鍣ㄤ汉缂撳瓨Path銆侀噴鏀句氦閫氭帶鍒堕攣
/// </summary>
public class ExecuteRobotSubTaskCommandHandler : IConsumer<ExecuteRobotSubTaskCommand>
{
    private readonly ILogger<ExecuteRobotSubTaskCommandHandler> _logger;
    private readonly IRobotSubTaskRepository _robotSubTaskRepository;
    private readonly IRobotTaskRepository _robotTaskRepository;
    private readonly IRobotRepository _robotRepository;
    private readonly IRobotCacheService _robotCacheService;
    private readonly AgvPathService _agvPathService;
    private readonly IProtocolServiceFactory _protocolServiceFactory;

    public ExecuteRobotSubTaskCommandHandler(
        ILogger<ExecuteRobotSubTaskCommandHandler> logger,
        IRobotSubTaskRepository robotSubTaskRepository,
        IRobotTaskRepository robotTaskRepository,
        IRobotRepository robotRepository,
        IRobotCacheService robotCacheService,
        AgvPathService agvPathService,
        IProtocolServiceFactory protocolServiceFactory)
    {
        _logger = logger;
        _robotSubTaskRepository = robotSubTaskRepository;
        _robotTaskRepository = robotTaskRepository;
        _robotRepository = robotRepository;
        _robotCacheService = robotCacheService;
        _agvPathService = agvPathService;
        _protocolServiceFactory = protocolServiceFactory;
    }

    public async Task Consume(ConsumeContext<ExecuteRobotSubTaskCommand> context)
    {
        var command = context.Message;
        try
        {
            var subTask = await _robotSubTaskRepository.GetByIdWithDetailsAsync(command.SubTaskId, context.CancellationToken);
            if (subTask == null)
            {
                await context.RespondAsync(ApiResponse.Failed($"未找到子任务ID为 {command.SubTaskId} 的任务"));
                return;
            }

            var robotId = subTask.RobotId ?? Guid.Empty;

            try
            {
                if (robotId != Guid.Empty)
                {
                    var robot = await _robotRepository.GetByIdAsync(robotId, context.CancellationToken);
                    if (robot != null)
                    {
                        var protocolService = _protocolServiceFactory.GetService(robot);
                        await protocolService.ClearAllVdaPathCacheAsync(robotId);
                    }
                    else
                    {
                        _logger.LogWarning("[鎵ц瀛愪换鍔 娓呯悊VDA璺緞缂撳瓨澶辫触锛屾満鍣ㄤ汉涓嶅瓨鍦? RobotId={RobotId}, SubTaskId={SubTaskId}",
                            robotId, command.SubTaskId);
                    }
                }
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "[鎵ц瀛愪换鍔 娓呯悊VDA璺緞缂撳瓨寮傚父: RobotId={RobotId}, SubTaskId={SubTaskId}",
                    robotId, command.SubTaskId);
            }

            await ClearRobotCachePathAsync(robotId, context.CancellationToken);

            if (robotId != Guid.Empty)
            {
                await _agvPathService.ReleaseAllLocksAsync(robotId);
            }
            // 将当前子任务与父任务恢复为等待中,便于重新调度执行
            subTask.Status = TaskStatus.Pending;
            subTask.UpdatedAt = DateTime.Now;

            // var task = subTask.Task ?? await _robotTaskRepository.GetByIdAsync(subTask.TaskId, context.CancellationToken);
            // if (task != null)
            // {
            //     task.Status = TaskStatus.Pending;
            //     task.UpdatedAt = DateTime.Now;
            //     await _robotTaskRepository.UpdateAsync(task, context.CancellationToken);
            // }

            await _robotSubTaskRepository.UpdateAsync(subTask, context.CancellationToken);
            await _robotSubTaskRepository.SaveChangesAsync(context.CancellationToken);
            

            await context.RespondAsync(ApiResponse.Successful("鎵ц鎴愬姛"));
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "鎵ц瀛愪换鍔″け璐? SubTaskId={SubTaskId}", command.SubTaskId);
            await context.RespondAsync(ApiResponse.Failed(ex.Message));
        }
    }

    private async Task ClearRobotCachePathAsync(Guid robotId, CancellationToken cancellationToken)
    {
        try
        {
            if (robotId == Guid.Empty) return;

            var robot = await _robotRepository.GetByIdAsync(robotId, cancellationToken);
            if (robot == null)
            {
                _logger.LogWarning("[鎵ц瀛愪换鍔 娓呯┖缂撳瓨Path澶辫触锛屾満鍣ㄤ汉涓嶅瓨鍦? RobotId={RobotId}", robotId);
                return;
            }

            await _robotCacheService.SetLocationValueAsync(
                robot.RobotManufacturer, robot.RobotSerialNumber, "Path", "");
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "[鎵ц瀛愪换鍔 娓呯┖鏈哄櫒浜虹紦瀛楶ath寮傚父: RobotId={RobotId}", robotId);
        }
    }
}