本次提交包含多项代码优化与规范修正: 1. 文档与注释优化:修正注释术语、补充注解与FR编号 2. 代码格式调整:统一空格、换行与缩进规范 3. 类型与接口完善:补充__all__导出、修正返回类型注解 4. 错误处理增强:新增领域错误类与校验逻辑 5. 依赖与导入调整:修复路径引用、统一时区导入 6. 协议与契约更新:完善接口文档与一致性注解
98 lines
3.2 KiB
Python
98 lines
3.2 KiB
Python
"""栅栏 DTO。
|
||
|
||
定义并发回复栅栏相关的不可变值对象,包括栅栏裁决、栅栏代际与栅栏
|
||
上下文。所有 DTO 均为 ``dataclass(frozen=True)``,仅依赖标准库,
|
||
用于并发回复栅栏的代际控制与过期裁决(FR-23)。
|
||
"""
|
||
|
||
from __future__ import annotations
|
||
|
||
from dataclasses import dataclass
|
||
from datetime import datetime
|
||
|
||
from yuxi.channels.contract.errors import ValidationError
|
||
|
||
|
||
@dataclass(frozen=True)
|
||
class FenceVerdict:
|
||
"""栅栏裁决。
|
||
|
||
描述栅栏对一次回复的过期裁决,包括是否过期、当前代际与可选的
|
||
过期代际,用于决定是否抑制过期回复。
|
||
|
||
字段:
|
||
is_stale: 是否过期。
|
||
current_generation: 当前代际。
|
||
stale_generation: 过期代际(可选)。
|
||
"""
|
||
|
||
is_stale: bool
|
||
current_generation: int
|
||
stale_generation: int | None = None
|
||
|
||
|
||
@dataclass(frozen=True)
|
||
class FenceGeneration:
|
||
"""栅栏代际。
|
||
|
||
描述会话的栅栏代际状态,包括当前代际与可见代际,用于代际比较与
|
||
过期判定。
|
||
|
||
字段:
|
||
conversation_id: 会话 ID。
|
||
current_generation: 当前代际。
|
||
visible_generation: 可见代际。
|
||
"""
|
||
|
||
conversation_id: str
|
||
current_generation: int
|
||
visible_generation: int
|
||
|
||
def __post_init__(self) -> None:
|
||
"""校验 conversation_id 非空与代际非负。
|
||
|
||
``conversation_id`` 必须非空,``current_generation`` 与
|
||
``visible_generation`` 必须非负,在构造时即抛出 ``ValidationError``,
|
||
避免空会话 ID 或负代际导致栅栏代际比较失效(INV-8 / FR-23)。
|
||
"""
|
||
if not self.conversation_id:
|
||
raise ValidationError("conversation_id", "must not be empty")
|
||
if self.current_generation < 0:
|
||
raise ValidationError("current_generation", "must not be negative")
|
||
if self.visible_generation < 0:
|
||
raise ValidationError("visible_generation", "must not be negative")
|
||
|
||
|
||
@dataclass(frozen=True)
|
||
class FenceContext:
|
||
"""栅栏上下文。
|
||
|
||
描述栅栏的执行上下文,包括会话 ID、代际、起始时间与 TTL,用于
|
||
栅栏生命周期管理与过期清理。
|
||
|
||
字段:
|
||
conversation_id: 会话 ID。
|
||
generation: 代际。
|
||
started_at: 起始时间。
|
||
ttl_seconds: TTL(秒,默认 120,与配置项 ``fence_ttl_seconds`` 一致)。
|
||
"""
|
||
|
||
conversation_id: str
|
||
generation: int
|
||
started_at: datetime
|
||
ttl_seconds: int = 120
|
||
|
||
def __post_init__(self) -> None:
|
||
"""校验 conversation_id 非空、generation 非负与 ttl_seconds 为正整数。
|
||
|
||
``conversation_id`` 必须非空,``generation`` 必须非负,``ttl_seconds``
|
||
必须为正整数,在构造时即抛出 ``ValidationError``,避免空会话 ID、负
|
||
代际或非正 TTL 导致栅栏生命周期管理失效(INV-8 / FR-23)。
|
||
"""
|
||
if not self.conversation_id:
|
||
raise ValidationError("conversation_id", "must not be empty")
|
||
if self.generation < 0:
|
||
raise ValidationError("generation", "must not be negative")
|
||
if self.ttl_seconds <= 0:
|
||
raise ValidationError("ttl_seconds", "must be a positive integer")
|