using Newtonsoft.Json;
using WIDESEAWCS_Common;
using WIDESEAWCS_Core.Caches;
using WIDESEAWCS_QuartzJob;
namespace WIDESEAWCS_Tasks
{
///
/// 机械手状态管理器 - 负责RobotSocketState的安全更新和克隆
///
public class RobotStateManager
{
private readonly ICacheService _cache;
public RobotStateManager(ICacheService cache)
{
_cache = cache;
}
///
/// 安全更新RobotSocketState缓存,防止并发覆盖
///
/// 设备IP地址
/// 更新状态的委托(传入当前状态,返回修改后的新状态)
/// 是否更新成功
public bool TryUpdateStateSafely(string ipAddress, Func updateAction)
{
var cacheKey = GetCacheKey(ipAddress);
var currentState = _cache.Get(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
);
}
///
/// 安全更新RobotSocketState缓存(简单版本)
///
/// 设备IP地址
/// 新状态(会被更新Version字段)
/// 是否更新成功
public bool TryUpdateStateSafely(string ipAddress, RobotSocketState newState)
{
var cacheKey = GetCacheKey(ipAddress);
var currentState = _cache.Get(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
);
}
///
/// 克隆RobotSocketState对象(创建深拷贝)
///
public RobotSocketState CloneState(RobotSocketState source)
{
// 使用序列化/反序列化进行深拷贝
var json = JsonConvert.SerializeObject(source);
return JsonConvert.DeserializeObject(json) ?? new RobotSocketState { IPAddress = source.IPAddress };
}
///
/// 获取Redis缓存键
///
public static string GetCacheKey(string ipAddress)
{
return $"{RedisPrefix.Code}:{RedisName.SocketDevices}:{ipAddress}";
}
///
/// 从缓存获取状态
///
public RobotSocketState? GetState(string ipAddress)
{
return _cache.Get(GetCacheKey(ipAddress));
}
///
/// 获取或创建状态
///
public RobotSocketState GetOrCreateState(string ipAddress, RobotCraneDevice robotCrane)
{
return _cache.GetOrAdd(GetCacheKey(ipAddress), _ => new RobotSocketState
{
IPAddress = ipAddress,
RobotCrane = robotCrane
});
}
}
}