100 lines
4.7 KiB
C#
100 lines
4.7 KiB
C#
|
|
namespace SHH.CameraSdk;
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// [决策引擎] 故障自愈策略 (V3.3.1 修复版)
|
|||
|
|
/// 核心职责:根据设备错误码特征,智能裁决系统应采取的恢复动作,实现故障自动化处理
|
|||
|
|
/// 关键修复(Bug R):
|
|||
|
|
/// <para>1. 致命错误防护:对 InvalidCredentials/AccountLocked 等错误禁止重试,防止账号被锁、IP 拉黑</para>
|
|||
|
|
/// <para>2. 未知错误保守策略:对 Unknown 错误采用 ManualIntervention,避免未知风险扩散</para>
|
|||
|
|
/// 设计原则:最小化风险、最大化自愈率,区分可重试/不可重试/需人工干预的错误类型
|
|||
|
|
/// </summary>
|
|||
|
|
public static class RecoveryPolicy
|
|||
|
|
{
|
|||
|
|
#region --- 1. 核心决策逻辑:错误码→自愈动作映射 ---
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 根据相机错误码判定对应的故障自愈动作
|
|||
|
|
/// </summary>
|
|||
|
|
/// <param name="code">设备上报的错误码</param>
|
|||
|
|
/// <returns>标准化的自愈动作指令</returns>
|
|||
|
|
public static RecoveryAction GetAction(CameraErrorCode code)
|
|||
|
|
{
|
|||
|
|
return code switch
|
|||
|
|
{
|
|||
|
|
// ========== 场景 A: 网络类故障 (可自愈) ==========
|
|||
|
|
// 策略:指数退避重试
|
|||
|
|
// 理由:网络波动、超时、闪断为暂时性故障,延迟重试大概率恢复
|
|||
|
|
CameraErrorCode.NetworkUnreachable or
|
|||
|
|
CameraErrorCode.NetworkSendError or
|
|||
|
|
CameraErrorCode.NetworkRecvError or
|
|||
|
|
CameraErrorCode.Timeout or
|
|||
|
|
CameraErrorCode.SocketError or
|
|||
|
|
CameraErrorCode.StreamInterrupted or
|
|||
|
|
CameraErrorCode.DeviceRebooting => RecoveryAction.RetryWithBackoff,
|
|||
|
|
|
|||
|
|
// ========== 场景 B: 资源繁忙类故障 (可自愈) ==========
|
|||
|
|
// 策略:指数退避重试
|
|||
|
|
// 理由:设备连接数满、缓冲区溢出,等待资源释放后可恢复
|
|||
|
|
CameraErrorCode.DeviceResourceBusy or
|
|||
|
|
CameraErrorCode.DeviceBufferOverflow or
|
|||
|
|
CameraErrorCode.DeviceBusy or
|
|||
|
|
CameraErrorCode.OperationNotFinished or
|
|||
|
|
CameraErrorCode.PortPoolExhausted or
|
|||
|
|
CameraErrorCode.MaxConnectionsReached or
|
|||
|
|
CameraErrorCode.MaxStreamExceeded => RecoveryAction.RetryWithBackoff,
|
|||
|
|
|
|||
|
|
// ========== 场景 C: 致命错误 (不可自愈,禁止重试) ==========
|
|||
|
|
// 策略:立即停止
|
|||
|
|
// 理由:密码错误、账号锁定、组件缺失等故障,重试无意义且会加剧风险(账号锁死、日志爆炸)
|
|||
|
|
CameraErrorCode.InvalidCredentials or
|
|||
|
|
CameraErrorCode.AccessDenied or
|
|||
|
|
CameraErrorCode.UserNotExist or
|
|||
|
|
CameraErrorCode.AccountLocked or
|
|||
|
|
CameraErrorCode.SessionExpired or
|
|||
|
|
CameraErrorCode.InvalidChannel or
|
|||
|
|
CameraErrorCode.IpConflict or
|
|||
|
|
CameraErrorCode.SdkNotInitialized or
|
|||
|
|
CameraErrorCode.ComponentLoadFailed or
|
|||
|
|
CameraErrorCode.EncryptionLibError => RecoveryAction.FatalStop,
|
|||
|
|
|
|||
|
|
// ========== 场景 D: 硬件故障 (需人工干预) ==========
|
|||
|
|
// 策略:人工介入
|
|||
|
|
// 理由:硬盘损坏、存储满等故障属于硬件层面,软件无法修复
|
|||
|
|
CameraErrorCode.HardwareFault or
|
|||
|
|
CameraErrorCode.StorageError or
|
|||
|
|
CameraErrorCode.DiskFull or
|
|||
|
|
CameraErrorCode.DiskReadOnly => RecoveryAction.ManualIntervention,
|
|||
|
|
|
|||
|
|
// ========== 场景 E: 正常状态 ==========
|
|||
|
|
CameraErrorCode.Success => RecoveryAction.None,
|
|||
|
|
|
|||
|
|
// ========== 场景 F: 未知错误 (关键修复 Bug R) ==========
|
|||
|
|
// 旧策略:盲目重试 → 新策略:人工干预
|
|||
|
|
// 理由:未知错误可能包含 IP 拉黑、协议不兼容等严重问题,重试会扩大风险
|
|||
|
|
_ => RecoveryAction.ManualIntervention
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
#endregion
|
|||
|
|
|
|||
|
|
#region --- 2. 辅助算法:指数退避延迟计算 ---
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 获取建议的指数退避延迟时间(毫秒)
|
|||
|
|
/// 算法公式:delay = min(2^n * 1000, 120000),n = 当前重试次数
|
|||
|
|
/// 限流规则:第一次 2s → 第二次 4s → ... → 第六次 64s → 上限 120s(2分钟)
|
|||
|
|
/// </summary>
|
|||
|
|
/// <param name="retryCount">当前重试次数(从 1 开始计数)</param>
|
|||
|
|
/// <returns>延迟毫秒数</returns>
|
|||
|
|
public static int GetRetryDelay(int retryCount)
|
|||
|
|
{
|
|||
|
|
// 限制重试次数最大为 7,防止指数爆炸导致数值溢出
|
|||
|
|
int exponent = Math.Min(retryCount, 7);
|
|||
|
|
// 计算指数退避秒数
|
|||
|
|
int delaySeconds = (int)Math.Pow(2, exponent);
|
|||
|
|
// 转换为毫秒并限制上限为 2 分钟(120000ms)
|
|||
|
|
return Math.Min(delaySeconds * 1000, 120000);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
#endregion
|
|||
|
|
}
|