"""扩展点协议。 定义扩展点相关的枚举、不可变值对象与 Stage Protocol,包括冲突策略、 失败策略、阶段槽位、事件订阅、配置源与管道阶段协议。 插件通过扩展点向宿主注入自身逻辑,宿主按优先级串联执行。 扩展点失败策略(§9.3):每个扩展点必须声明 ``failure_policy`` 字段, 标识插件失败时的处理方式(降级 / 熔断 / 隔离),确保插件故障隔离性 (§9.5"插件失败不得拖垮宿主")。 命名约定: - ``FailureStrategy``(本模块):**阶段执行**失败策略(TERMINATE / SKIP / COMPENSATE / DEGRADE),由 ``Stage.failure`` 字段使用, 描述管道阶段执行失败时的处理方式。 - ``FailurePolicy``(manifest 模块):**插件隔离**失败策略 (DEGRADE / CIRCUIT_BREAK / ISOLATE),由扩展点 ``failure_policy`` 字段使用,描述插件故障时的隔离方式。 两者语义不同,字段与类型必须一致命名以避免混淆。 """ from __future__ import annotations from dataclasses import dataclass from enum import StrEnum from typing import Any, Protocol, runtime_checkable from yuxi.channels.contract.dtos.plugin import ( ConfigDecryptor, ConfigLoader, EventHandler, ) from yuxi.channels.contract.plugin.manifest import FailurePolicy class ConflictStrategy(StrEnum): """冲突策略。 标识同一锚点多个插件阶段的冲突解决方式。继承 ``str, Enum`` 以支持 JSON 序列化与字符串比较。 取值: CHAIN: 链式调用(按优先级串联执行)。 REJECT: 拒绝(同操作 ID 冲突时拒绝装配)。 OVERRIDE: 覆盖(后注册者覆盖先注册者)。 """ CHAIN = "chain" REJECT = "reject" OVERRIDE = "override" class FailureStrategy(StrEnum): """阶段失败策略。 标识管道阶段执行失败时的处理方式。继承 ``str, Enum`` 以支持 JSON 序列化 与字符串比较。 取值: TERMINATE: 终止管道。 SKIP: 跳过阶段。 COMPENSATE: 执行补偿。 DEGRADE: 降级。 """ TERMINATE = "terminate" SKIP = "skip" COMPENSATE = "compensate" DEGRADE = "degrade" @dataclass(frozen=True) class StageSlot: """阶段槽位。 描述插件向管道锚点注入的阶段槽位,包括管道名、锚点、阶段实例、优先级、 是否允许多个阶段共存、冲突策略与失败策略,用于扩展点装配。 字段: pipeline: 管道名(inbound | outbound | control)。 anchor: 锚点(阶段名,如 before:route | after:security)。 stage: Stage Protocol 实例。 priority: 优先级(默认 100,越小越先执行)。 multi: 是否允许多个阶段插入同一锚点(默认 False)。 conflict_strategy: 冲突策略(默认 CHAIN)。 failure_policy: 插件隔离失败策略(默认 DEGRADE,插件失败时降级 跳过,不拖垮宿主 §9.5)。 """ pipeline: str anchor: str stage: Stage priority: int = 100 multi: bool = False conflict_strategy: ConflictStrategy = ConflictStrategy.CHAIN failure_policy: FailurePolicy = FailurePolicy.DEGRADE @dataclass(frozen=True) class EventSubscription: """事件订阅。 描述插件对领域事件的订阅,包括事件类型、处理器、优先级与失败策略, 用于事件总线分发注册。 字段: event_type: 事件类型(PairingApproved | ConfigChanged | PluginFailed | ...)。 handler: 事件处理 Protocol 实例。 priority: 优先级(默认 100)。 failure_policy: 插件隔离失败策略(默认 DEGRADE,handler 失败时 跳过本次调用,不中断其他订阅者 §9.5)。 """ event_type: str handler: EventHandler priority: int = 100 failure_policy: FailurePolicy = FailurePolicy.DEGRADE @dataclass(frozen=True) class ConfigSource: """配置源。 描述插件提供的配置源,包括源 ID、加载器、可选解密器与失败策略,用于 配置端口的多源加载。 字段: source_id: 源 ID。 loader: 配置加载 Protocol 实例。 decryptor: 配置解密 Protocol 实例(可选)。 failure_policy: 插件隔离失败策略(默认 DEGRADE,加载失败时 跳过此源,回退至其他配置源 §9.5)。 """ source_id: str loader: ConfigLoader decryptor: ConfigDecryptor | None = None failure_policy: FailurePolicy = FailurePolicy.DEGRADE @runtime_checkable class Stage(Protocol): """管道阶段 Protocol。 由插件实现,描述管道阶段的元信息与处理方法。使用 ``@runtime_checkable`` 装饰以支持 ``isinstance`` 检查。阶段处理为 异步方法,由管道按优先级串联调用。 与应用层 ``AppStage`` Protocol 对齐: - ``compensate`` 为 ``str | None``,携带补偿阶段名称(如 "outbox-rollback"),None 表示无补偿; - ``process`` 返回 ``bool``:True 表示成功,False 或抛出异常表示 失败。 优先级规则(§7.8): - 1~49:安全/合规相关阶段(必须最先执行),如 DM 安全检查、审计前置。 - 50~99:业务增强阶段(在核心阶段之前增强上下文),如渠道路由增强、 身份预解析。 - 100:默认优先级,大多数插件阶段。 - 101~200:业务后处理阶段(在核心阶段之后处理),如消息格式化增强、 指标采集。 - 201+:可观测性/诊断阶段(必须最后执行),如追踪收尾、诊断快照。 冲突解决: - 同一锚点、相同优先级的多个插件阶段 **必须** 拒绝装配,并报告冲突详情。 - 插件 **不得** 使用 ``replace`` 锚点覆盖核心阶段,除非扩展点显式允许。 """ id: str reads: tuple[str, ...] writes: tuple[str, ...] idempotent: bool thread_safe: bool failure: FailureStrategy compensate: str | None async def process(self, context: Any) -> bool: """处理管道阶段。 参数: context: 管道上下文。 返回: True 表示成功,False 或抛出异常表示失败。 @consistency: 阶段处理(stage-processed),按 ``Stage.reads`` / ``Stage.writes`` 读写上下文;失败按 ``Stage.failure`` 策略处理。 @idempotent: 取决于 ``Stage.idempotent`` 字段声明,由阶段实现者明确标注。 """ ...