ExecuteRobotSubTaskCommandHandler.cs
5.4 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
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 中前置清理保持一致:
/// 清理 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, "[执行子任务] 清空机器人缓存Path异常: RobotId={RobotId}", robotId);
}
}
}