Files
Ayay/SHH.CameraSdk/Abstractions/Errors/RecoveryPolicy.cs

100 lines
4.7 KiB
C#
Raw Normal View History

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 → 上限 120s2分钟
/// </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
}