From 49a177598902683ea538de64848499911f4f25b9 Mon Sep 17 00:00:00 2001
From: wanshenmean <cathay_xy@163.com>
Date: 星期日, 19 四月 2026 19:25:35 +0800
Subject: [PATCH] refactor(RobotState): 将 RobotStateManager 从 Redis 改为依赖数据库仓储 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
---
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/RobotJob/RobotStateManager.cs | 140 +++++++++++++++++-----------------------------
1 files changed, 53 insertions(+), 87 deletions(-)
diff --git a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/RobotJob/RobotStateManager.cs b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/RobotJob/RobotStateManager.cs
index 89f0910..028305d 100644
--- a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/RobotJob/RobotStateManager.cs
+++ b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/RobotJob/RobotStateManager.cs
@@ -1,9 +1,9 @@
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using WIDESEAWCS_Common;
-using WIDESEAWCS_Core.Caches;
using WIDESEAWCS_Core.LogHelper;
-using WIDESEAWCS_QuartzJob;
+using WIDESEAWCS_ITaskInfoRepository;
+using WIDESEAWCS_Model.Models;
namespace WIDESEAWCS_Tasks
{
@@ -11,15 +11,15 @@
/// 鏈烘鎵嬬姸鎬佺鐞嗗櫒 - 璐熻矗 RobotSocketState 鐨勭嚎绋嬪畨鍏ㄦ洿鏂板拰鍏嬮殕
/// </summary>
/// <remarks>
- /// 鏍稿績鍔熻兘鏄�氳繃缂撳瓨鏈嶅姟锛圛CacheService锛夌鐞� Redis 涓殑鏈烘鎵嬬姸鎬併��
- /// 鎻愪緵涔愯骞跺彂鎺у埗锛岄�氳繃鐗堟湰鍙凤紙Version锛夊瓧娈甸槻姝㈠苟鍙戞洿鏂版椂鐨勬暟鎹鐩栭棶棰樸��
+ /// 鏍稿績鍔熻兘鏄�氳繃 IRobotStateRepository 绠$悊鏁版嵁搴撲腑鐨勬満姊版墜鐘舵�併��
+ /// 鎻愪緵涔愯骞跺彂鎺у埗锛岄�氳繃 RowVersion 闃叉骞跺彂鏇存柊鏃剁殑鏁版嵁瑕嗙洊闂銆�
/// </remarks>
public class RobotStateManager
{
/// <summary>
- /// 缂撳瓨鏈嶅姟瀹炰緥锛岀敤浜庤鍐� Redis 涓殑鐘舵�佹暟鎹�
+ /// 浠撳偍鏈嶅姟瀹炰緥锛岀敤浜庤鍐欐暟鎹簱涓殑鐘舵�佹暟鎹�
/// </summary>
- private readonly ICacheService _cache;
+ private readonly IRobotStateRepository _repository;
/// <summary>
/// 鏃ュ織璁板綍鍣�
@@ -29,11 +29,11 @@
/// <summary>
/// 鏋勯�犲嚱鏁�
/// </summary>
- /// <param name="cache">缂撳瓨鏈嶅姟瀹炰緥锛堥�氬父涓� HybridCacheService锛�</param>
+ /// <param name="repository">浠撳偍鏈嶅姟瀹炰緥</param>
/// <param name="logger">鏃ュ織璁板綍鍣�</param>
- public RobotStateManager(ICacheService cache, ILogger logger)
+ public RobotStateManager(IRobotStateRepository repository, ILogger logger)
{
- _cache = cache;
+ _repository = repository;
_logger = logger;
}
@@ -41,96 +41,82 @@
/// 瀹夊叏鏇存柊 RobotSocketState 缂撳瓨锛岄槻姝㈠苟鍙戣鐩�
/// </summary>
/// <remarks>
- /// 浣跨敤涔愯骞跺彂妯″紡锛氬厛璇诲彇褰撳墠鐗堟湰鍙凤紝鎵ц鏇存柊鏃舵鏌ョ増鏈槸鍚︿竴鑷淬��
- /// 濡傛灉鐗堟湰涓嶅尮閰嶏紙璇存槑鏈夊叾浠栫嚎绋嬪凡鏇存柊锛夛紝鍒欐洿鏂板け璐ヨ繑鍥� false銆�
+ /// 浣跨敤涔愯骞跺彂妯″紡锛氬厛璇诲彇褰撳墠 RowVersion锛屾墽琛屾洿鏂版椂妫�鏌ョ増鏈槸鍚︿竴鑷淬��
+ /// 濡傛灉 RowVersion 涓嶅尮閰嶏紙璇存槑鏈夊叾浠栫嚎绋嬪凡鏇存柊锛夛紝鍒欐洿鏂板け璐ヨ繑鍥� false銆�
/// </remarks>
- /// <param name="ipAddress">璁惧 IP 鍦板潃锛岀敤浜庢瀯寤虹紦瀛橀敭</param>
+ /// <param name="ipAddress">璁惧 IP 鍦板潃</param>
/// <param name="updateAction">鏇存柊鐘舵�佺殑濮旀墭鍑芥暟锛屼紶鍏ュ綋鍓嶇姸鎬佸壇鏈紝杩斿洖淇敼鍚庣殑鏂扮姸鎬�</param>
/// <returns>鏄惁鏇存柊鎴愬姛锛沠alse 琛ㄧず鐗堟湰鍐茬獊鎴栫姸鎬佷笉瀛樺湪</returns>
public bool TryUpdateStateSafely(string ipAddress, Func<RobotSocketState, RobotSocketState> updateAction)
{
- // 鏋勫缓 Redis 缂撳瓨閿紝鏍煎紡锛歿RedisPrefix.Code}:{RedisName.SocketDevices}:{ipAddress}
- var cacheKey = GetCacheKey(ipAddress);
+ // 浠庢暟鎹簱鑾峰彇褰撳墠瀛樺偍鐨勭姸鎬�
+ var currentEntity = _repository.GetByIp(ipAddress);
- // 浠庣紦瀛樿幏鍙栧綋鍓嶅瓨鍌ㄧ殑鐘舵��
- var currentState = _cache.Get<RobotSocketState>(cacheKey);
-
- // 濡傛灉缂撳瓨涓笉瀛樺湪璇ヨ澶囩殑鐘舵�侊紝鐩存帴杩斿洖 false锛堝簲鐢� GetOrCreateState 鍏堝垱寤猴級
- if (currentState == null)
+ if (currentEntity == null)
{
return false;
}
- // 璁板綍褰撳墠瀛樺偍鐨勭増鏈彿锛屼綔涓烘洿鏂版椂鐨勬湡鏈涚増鏈�
- var expectedVersion = currentState.Version;
+ // 璁板綍褰撳墠瀛樺偍鐨� RowVersion锛屼綔涓烘洿鏂版椂鐨勬湡鏈涚増鏈�
+ var expectedRowVersion = currentEntity.RowVersion;
- // 鍒涘缓鐘舵�佺殑娣辨嫹璐濆壇鏈紝閬垮厤鐩存帴淇敼鍘熷璞″紩鐢�
- // 杩欐牱鍙互纭繚鍦ㄥ绾跨▼鐜涓嬶紝姣忎釜绾跨▼鎿嶄綔鐨勬槸鐙珛鐨勭姸鎬佸壇鏈�
- var stateCopy = CloneState(currentState);
+ // 鍒涘缓鐘舵�佺殑娣辨嫹璐濆壇鏈紙浣跨敤 JSON 搴忓垪鍖栧疄鐜帮級
+ var stateCopy = CloneState(_repository.ToSocketState(currentEntity));
// 鎵ц璋冪敤鑰呮彁渚涚殑鏇存柊閫昏緫锛屼紶鍏ュ壇鏈姸鎬侊紝鑾峰彇鏂扮殑鐘舵�佸璞�
var newState = updateAction(stateCopy);
- // 灏嗘柊鐘舵�佺殑鐗堟湰鍙锋洿鏂颁负鏈�鏂扮殑鏃堕棿鎴筹紝琛ㄧず鏁版嵁宸叉洿鏂�
- newState.Version = DateTime.UtcNow.Ticks;
+ // 灏嗘柊鐘舵�佽浆鎹负鏁版嵁搴撳疄浣�
+ var newEntity = _repository.ToEntity(newState);
+ newEntity.RowVersion = Array.Empty<byte>(); // SqlSugar 浼氳嚜鍔ㄧ鐞�
+ newEntity.Id = currentEntity.Id;
- // 璋冪敤缂撳瓨鏈嶅姟鐨勫畨鍏ㄦ洿鏂版柟娉曪紝浼犲叆鏈熸湜鐗堟湰鍜岀増鏈彁鍙栧櫒
- // 濡傛灉褰撳墠鐗堟湰涓庢湡鏈涚増鏈笉涓�鑷达紙宸茶鍏朵粬绾跨▼鏇存柊锛夛紝鍒欐洿鏂板け璐�
- return _cache.TrySafeUpdate(
- cacheKey,
- newState,
- expectedVersion,
- s => s.Version // 鎸囧畾鍝釜瀛楁浣滀负鐗堟湰鍙�
- );
+ // 璋冪敤浠撳偍鐨勫畨鍏ㄦ洿鏂版柟娉曪紝浼犲叆鏈熸湜 RowVersion
+ // 濡傛灉 RowVersion 涓嶄竴鑷达紙宸茶鍏朵粬绾跨▼鏇存柊锛夛紝鍒欐洿鏂板け璐�
+ return _repository.TryUpdate(ipAddress, newEntity, expectedRowVersion);
}
/// <summary>
- /// 瀹夊叏鏇存柊 RobotSocketState 缂撳瓨鐨勯噸杞界増鏈紙鐩存帴浼犲叆鏂扮姸鎬侊級
+ /// 瀹夊叏鏇存柊 RobotSocketState 鐨勯噸杞界増鏈紙鐩存帴浼犲叆鏂扮姸鎬侊級
/// </summary>
/// <remarks>
/// 涓庝笂涓�涓噸杞界殑鍖哄埆锛氭鏂规硶鐩存帴鎺ユ敹瀹屾暣鐨勬柊鐘舵�佸璞★紝鑰屼笉鏄洿鏂板鎵樸��
- /// 濡傛灉璁惧鐘舵�佷笉瀛樺湪浜庣紦瀛樹腑锛屽垯鐩存帴娣诲姞鏂扮姸鎬併��
+ /// 濡傛灉鏁版嵁搴撲腑涓嶅瓨鍦ㄨ璁惧鐨勭姸鎬侊紝鍒欏垱寤烘柊璁板綍銆�
/// </remarks>
- /// <param name="ipAddress">璁惧 IP 鍦板潃锛岀敤浜庢瀯寤虹紦瀛橀敭</param>
- /// <param name="newState">鏂扮姸鎬佸璞★紙鏂规硶鍐呴儴浼氭洿鏂板叾 Version 瀛楁锛�</param>
+ /// <param name="ipAddress">璁惧 IP 鍦板潃</param>
+ /// <param name="newState">鏂扮姸鎬佸璞�</param>
/// <returns>鏄惁鏇存柊鎴愬姛锛涙柊寤鸿缃负 true</returns>
public bool TryUpdateStateSafely(string ipAddress, RobotSocketState newState)
{
- // 鏋勫缓 Redis 缂撳瓨閿�
- var cacheKey = GetCacheKey(ipAddress);
+ // 浠庢暟鎹簱鑾峰彇褰撳墠瀛樺偍鐨勭姸鎬�
+ var currentEntity = _repository.GetByIp(ipAddress);
- // 浠庣紦瀛樿幏鍙栧綋鍓嶅瓨鍌ㄧ殑鐘舵��
- var currentState = _cache.Get<RobotSocketState>(cacheKey);
-
- // 濡傛灉褰撳墠涓嶅瓨鍦ㄨ璁惧鐨勭姸鎬�
- if (currentState == null)
+ // 濡傛灉褰撳墠涓嶅瓨鍦ㄨ璁惧鐨勭姸鎬侊紝鍒涘缓鏂拌褰�
+ if (currentEntity == null)
{
- // 涓烘柊鐘舵�佽缃増鏈彿锛堟椂闂存埑锛�
- newState.Version = DateTime.UtcNow.Ticks;
- // 鐩存帴娣诲姞鍒扮紦瀛�
- _cache.AddObject(cacheKey, newState);
+ var entity = _repository.ToEntity(newState);
+ entity.CreateTime = DateTime.Now;
+ entity.UpdateTime = DateTime.Now;
+ _repository.GetOrCreate(newState.IPAddress, newState.RobotCrane ?? new RobotCraneDevice());
_logger.LogDebug("TryUpdateStateSafely锛氬垱寤烘柊鐘舵�侊紝IP: {IpAddress}", ipAddress);
QuartzLogger.Debug($"鍒涘缓鏂扮姸鎬侊紝IP: {ipAddress}", ipAddress);
return true;
}
- // 褰撳墠瀛樺湪鐘舵�侊紝璁板綍鏈熸湜鐗堟湰鍙风敤浜庝箰瑙傞攣妫�鏌�
- var expectedVersion = currentState.Version;
+ // 褰撳墠瀛樺湪鐘舵�侊紝璁板綍鏈熸湜 RowVersion 鐢ㄤ簬涔愯閿佹鏌�
+ var expectedRowVersion = currentEntity.RowVersion;
- // 鏇存柊鏂扮姸鎬佺殑鐗堟湰鍙蜂负鏈�鏂版椂闂存埑
- newState.Version = DateTime.UtcNow.Ticks;
+ // 灏嗘柊鐘舵�佽浆鎹负鏁版嵁搴撳疄浣�
+ var newEntity = _repository.ToEntity(newState);
+ newEntity.Id = currentEntity.Id;
+ newEntity.RowVersion = Array.Empty<byte>();
// 灏濊瘯瀹夊叏鏇存柊锛屽鏋滅増鏈啿绐佸垯杩斿洖 false
- bool success = _cache.TrySafeUpdate(
- cacheKey,
- newState,
- expectedVersion,
- s => s.Version
- );
+ bool success = _repository.TryUpdate(ipAddress, newEntity, expectedRowVersion);
if (!success)
{
- _logger.LogWarning("TryUpdateStateSafely锛氱増鏈啿绐侊紝鏇存柊澶辫触锛孖P: {IpAddress}锛屾湡鏈涚増鏈�: {ExpectedVersion}", ipAddress, expectedVersion);
+ _logger.LogWarning("TryUpdateStateSafely锛氱増鏈啿绐侊紝鏇存柊澶辫触锛孖P: {IpAddress}锛屾湡鏈涚増鏈瓧鑺傞暱搴�: {ExpectedLength}", ipAddress, expectedRowVersion.Length);
QuartzLogger.Warn($"鐗堟湰鍐茬獊锛屾洿鏂板け璐ワ紝IP: {ipAddress}", ipAddress);
}
@@ -148,55 +134,35 @@
/// <returns>鏂扮殑鐘舵�佸璞★紝鏄簮瀵硅薄鐨勬繁鎷疯礉</returns>
public RobotSocketState CloneState(RobotSocketState source)
{
- // 灏嗘簮瀵硅薄搴忓垪鍖栦负 JSON 瀛楃涓�
var json = JsonConvert.SerializeObject(source);
- // 鍙嶅簭鍒楀寲涓烘柊鐨� RobotSocketState 瀵硅薄
- // 濡傛灉鍙嶅簭鍒楀寲澶辫触锛堣繑鍥� null锛夛紝鍒涘缓涓�涓柊瀵硅薄骞跺鍒� IPAddress
return JsonConvert.DeserializeObject<RobotSocketState>(json) ?? new RobotSocketState { IPAddress = source.IPAddress };
}
/// <summary>
- /// 鑾峰彇 Redis 缂撳瓨閿�
- /// </summary>
- /// <remarks>
- /// 缂撳瓨閿牸寮忥細{RedisPrefix.Code}:{RedisName.SocketDevices}:{ipAddress}
- /// 渚嬪锛欳ode:SocketDevices:192.168.1.100
- /// </remarks>
- /// <param name="ipAddress">璁惧 IP 鍦板潃</param>
- /// <returns>瀹屾暣鐨� Redis 缂撳瓨閿�</returns>
- public static string GetCacheKey(string ipAddress)
- {
- return $"{RedisPrefix.Code}:{RedisName.SocketDevices}:{ipAddress}";
- }
-
- /// <summary>
- /// 浠庣紦瀛樿幏鍙栨満姊版墜鐘舵��
+ /// 浠庢暟鎹簱鑾峰彇鏈烘鎵嬬姸鎬�
/// </summary>
/// <param name="ipAddress">璁惧 IP 鍦板潃</param>
/// <returns>濡傛灉瀛樺湪鍒欒繑鍥炵姸鎬佸璞★紝鍚﹀垯杩斿洖 null</returns>
public RobotSocketState? GetState(string ipAddress)
{
- return _cache.Get<RobotSocketState>(GetCacheKey(ipAddress));
+ var entity = _repository.GetByIp(ipAddress);
+ return entity != null ? _repository.ToSocketState(entity) : null;
}
/// <summary>
/// 鑾峰彇鎴栧垱寤烘満姊版墜鐘舵��
/// </summary>
/// <remarks>
- /// 濡傛灉缂撳瓨涓凡瀛樺湪璇ヨ澶囩殑鐘舵�侊紝鐩存帴杩斿洖銆�
- /// 濡傛灉涓嶅瓨鍦紝鍒欏垱寤烘柊鐨勭姸鎬佸璞″苟瀛樺叆缂撳瓨锛岀劧鍚庤繑鍥炪��
+ /// 濡傛灉鏁版嵁搴撲腑宸插瓨鍦ㄨ璁惧鐨勭姸鎬侊紝鐩存帴杩斿洖銆�
+ /// 濡傛灉涓嶅瓨鍦紝鍒欏垱寤烘柊鐨勭姸鎬佽褰曞苟杩斿洖銆�
/// </remarks>
/// <param name="ipAddress">璁惧 IP 鍦板潃</param>
/// <param name="robotCrane">鏈哄櫒浜鸿澶囦俊鎭紝鐢ㄤ簬鍒濆鍖栨柊鐘舵��</param>
/// <returns>璇ヨ澶囩殑鐘舵�佸璞�</returns>
public RobotSocketState GetOrCreateState(string ipAddress, RobotCraneDevice robotCrane)
{
- // 浣跨敤缂撳瓨鏈嶅姟鐨� GetOrAdd 鏂规硶锛屽伐鍘傚嚱鏁板湪缂撳瓨鏈懡涓椂鍒涘缓鏂扮姸鎬�
- return _cache.GetOrAdd(GetCacheKey(ipAddress), _ => new RobotSocketState
- {
- IPAddress = ipAddress, // 璁剧疆 IP 鍦板潃浣滀负鏍囪瘑
- RobotCrane = robotCrane // 淇濆瓨璁惧淇℃伅
- });
+ var entity = _repository.GetOrCreate(ipAddress, robotCrane);
+ return _repository.ToSocketState(entity);
}
}
}
--
Gitblit v1.9.3