ForcePilot/backend/package/yuxi/channels/contract/dtos/degradation.py
Kris 00092c818e chore: 批量代码优化与规范完善
本次提交包含多项代码优化与规范修正:
1. 文档与注释优化:修正注释术语、补充注解与FR编号
2. 代码格式调整:统一空格、换行与缩进规范
3. 类型与接口完善:补充__all__导出、修正返回类型注解
4. 错误处理增强:新增领域错误类与校验逻辑
5. 依赖与导入调整:修复路径引用、统一时区导入
6. 协议与契约更新:完善接口文档与一致性注解
2026-07-03 19:18:13 +08:00

72 lines
2.4 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""优雅降级 DTO。
定义优雅降级FR-36的枚举与不可变值对象包括降级等级与恢复状态。
所有枚举继承 ``str, Enum`` 以支持 JSON 序列化DTO 均为
``dataclass(frozen=True)``,仅依赖标准库,用于插件失败后的降级状态
管理与恢复追踪。
"""
from __future__ import annotations
from dataclasses import dataclass
from datetime import datetime
from enum import StrEnum
from yuxi.channels.contract.errors import ValidationError
class DegradationLevel(StrEnum):
"""降级等级。
标识系统或渠道的降级状态,用于健康检查与降级决策。继承
``str, Enum`` 以支持 JSON 序列化与字符串比较。
取值:
HEALTHY: 所有插件运行正常。
DEGRADED: 部分插件失败但核心功能可用。
UNHEALTHY: 核心插件失败或数据库 / Redis 不可用。
"""
HEALTHY = "healthy"
DEGRADED = "degraded"
UNHEALTHY = "unhealthy"
@dataclass(frozen=True)
class RecoveryStatus:
"""恢复状态。
描述失败插件的恢复追踪状态,包括插件 ID、重试次数、上次重试时间、
下次重试时间、是否已恢复与失败原因,用于 FR-36 优雅降级的恢复
流程管理与诊断。
字段:
plugin_id: 插件 ID。
retry_count: 重试次数(默认 0上限 3
last_retry_at: 上次重试时间(可选)。
next_retry_at: 下次重试时间(可选)。
recovered: 是否已恢复(默认 False
failure_reason: 失败原因(可选,便于诊断)。
"""
plugin_id: str
retry_count: int = 0
last_retry_at: datetime | None = None
next_retry_at: datetime | None = None
recovered: bool = False
failure_reason: str | None = None
def __post_init__(self) -> None:
"""校验 plugin_id 非空与 retry_count 范围。
``plugin_id`` 必须非空,``retry_count`` 必须在 0-3 之间FR-36 上限 3
在构造时即抛出 ``ValidationError``adapter 不再做该校验INV-8
"""
if not self.plugin_id:
raise ValidationError("plugin_id", "must not be empty")
if self.retry_count < 0 or self.retry_count > 3:
raise ValidationError(
"retry_count",
"retry_count must be in [0, 3]",
)