RobotStatePersistenceService.cs
3.87 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
using System;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Rcs.Application.Services;
using Rcs.Domain.Repositories;
using Rcs.Shared.Utils;
namespace Rcs.Infrastructure.Services
{
/// <summary>
/// 机器人状态持久化服务 - 定时将Redis中的机器人状态和位置同步到数据库
/// @author zzy
/// </summary>
public class RobotStatePersistenceService : BackgroundService
{
private readonly ILogger<RobotStatePersistenceService> _logger;
private readonly IServiceProvider _serviceProvider;
private readonly IRobotCacheService _robotCacheService;
private readonly TimeSpan _syncInterval = TimeSpan.FromSeconds(3);
public RobotStatePersistenceService(
ILogger<RobotStatePersistenceService> logger,
IServiceProvider serviceProvider,
IRobotCacheService robotCacheService)
{
_logger = logger;
_serviceProvider = serviceProvider;
_robotCacheService = robotCacheService;
}
/// <summary>
/// 后台执行定时同步任务
/// @author zzy
/// </summary>
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
_logger.LogInformation("[状态持久化] 机器人状态持久化服务已启动,同步间隔: {Interval}秒", _syncInterval.TotalSeconds);
while (!stoppingToken.IsCancellationRequested)
{
try
{
await PersistRobotStatesAsync(stoppingToken);
}
catch (Exception ex)
{
_logger.LogError(ex, "[状态持久化] 同步机器人状态到数据库时发生错误");
}
await Task.Delay(_syncInterval, stoppingToken);
}
}
/// <summary>
/// 批量将Redis中的机器人状态和位置同步到数据库
/// @author zzy
/// </summary>
private async Task PersistRobotStatesAsync(CancellationToken cancellationToken)
{
var cacheData = await _robotCacheService.GetAllRobotCacheDataAsync();
var count = 0;
using var scope = _serviceProvider.CreateScope();
var robotRepo = scope.ServiceProvider.GetRequiredService<IRobotRepository>();
foreach (var (manufacturer, serialNumber, status, location) in cacheData)
{
if (cancellationToken.IsCancellationRequested) break;
var robot = await robotRepo.GetByManufacturerAndSerialNumberAsync(manufacturer, serialNumber, cancellationToken);
if (robot == null) continue;
// 更新状态
robot.UpdateDynamicStatus(
status: status.Status,
online: status.Online,
batteryLevel: status.BatteryLevel,
driving: status.Driving,
paused: status.Paused,
charging: status.Charging,
operatingMode: status.OperatingMode,
errors: status.Errors.ToJsonWithChinese());
// 更新位置
robot.UpdateLocation(
mapCode: location.MapId,
node: location.NodeId,
x: location.X,
y: location.Y,
theta: location.Theta);
await robotRepo.UpdateAsync(robot, cancellationToken);
await robotRepo.SaveChangesAsync(cancellationToken);
count++;
}
if (count > 0)
{
_logger.LogDebug("[状态持久化] 已同步 {Count} 个机器人状态到数据库", count);
}
}
}
}