using Newtonsoft.Json;
|
using WIDESEAWCS_Common;
|
using WIDESEAWCS_Core.Caches;
|
using WIDESEAWCS_QuartzJob;
|
|
namespace WIDESEAWCS_Tasks
|
{
|
/// <summary>
|
/// 机械手状态管理器 - 负责RobotSocketState的安全更新和克隆
|
/// </summary>
|
public class RobotStateManager
|
{
|
private readonly ICacheService _cache;
|
|
public RobotStateManager(ICacheService cache)
|
{
|
_cache = cache;
|
}
|
|
/// <summary>
|
/// 安全更新RobotSocketState缓存,防止并发覆盖
|
/// </summary>
|
/// <param name="ipAddress">设备IP地址</param>
|
/// <param name="updateAction">更新状态的委托(传入当前状态,返回修改后的新状态)</param>
|
/// <returns>是否更新成功</returns>
|
public bool TryUpdateStateSafely(string ipAddress, Func<RobotSocketState, RobotSocketState> updateAction)
|
{
|
var cacheKey = GetCacheKey(ipAddress);
|
var currentState = _cache.Get<RobotSocketState>(cacheKey);
|
|
if (currentState == null)
|
{
|
return false;
|
}
|
|
// 使用当前存储的版本号作为期望版本
|
var expectedVersion = currentState.Version;
|
|
// 创建状态副本进行修改(避免修改原对象引用)
|
var stateCopy = CloneState(currentState);
|
var newState = updateAction(stateCopy);
|
newState.Version = DateTime.UtcNow.Ticks;
|
|
return _cache.TrySafeUpdate(
|
cacheKey,
|
newState,
|
expectedVersion,
|
s => s.Version
|
);
|
}
|
|
/// <summary>
|
/// 安全更新RobotSocketState缓存(简单版本)
|
/// </summary>
|
/// <param name="ipAddress">设备IP地址</param>
|
/// <param name="newState">新状态(会被更新Version字段)</param>
|
/// <returns>是否更新成功</returns>
|
public bool TryUpdateStateSafely(string ipAddress, RobotSocketState newState)
|
{
|
var cacheKey = GetCacheKey(ipAddress);
|
var currentState = _cache.Get<RobotSocketState>(cacheKey);
|
|
if (currentState == null)
|
{
|
// 当前不存在,直接添加
|
newState.Version = DateTime.UtcNow.Ticks;
|
_cache.AddObject(cacheKey, newState);
|
return true;
|
}
|
|
// 使用当前存储的版本号作为期望版本
|
var expectedVersion = currentState.Version;
|
|
// 更新新状态的版本号为最新时间戳
|
newState.Version = DateTime.UtcNow.Ticks;
|
|
return _cache.TrySafeUpdate(
|
cacheKey,
|
newState,
|
expectedVersion,
|
s => s.Version
|
);
|
}
|
|
/// <summary>
|
/// 克隆RobotSocketState对象(创建深拷贝)
|
/// </summary>
|
public RobotSocketState CloneState(RobotSocketState source)
|
{
|
// 使用序列化/反序列化进行深拷贝
|
var json = JsonConvert.SerializeObject(source);
|
return JsonConvert.DeserializeObject<RobotSocketState>(json) ?? new RobotSocketState { IPAddress = source.IPAddress };
|
}
|
|
/// <summary>
|
/// 获取Redis缓存键
|
/// </summary>
|
public static string GetCacheKey(string ipAddress)
|
{
|
return $"{RedisPrefix.Code}:{RedisName.SocketDevices}:{ipAddress}";
|
}
|
|
/// <summary>
|
/// 从缓存获取状态
|
/// </summary>
|
public RobotSocketState? GetState(string ipAddress)
|
{
|
return _cache.Get<RobotSocketState>(GetCacheKey(ipAddress));
|
}
|
|
/// <summary>
|
/// 获取或创建状态
|
/// </summary>
|
public RobotSocketState GetOrCreateState(string ipAddress, RobotCraneDevice robotCrane)
|
{
|
return _cache.GetOrAdd(GetCacheKey(ipAddress), _ => new RobotSocketState
|
{
|
IPAddress = ipAddress,
|
RobotCrane = robotCrane
|
});
|
}
|
}
|
}
|