Skip to content

refactor(dispatch): 统一分发内核 + 事件广播并发加固(HIGH) + 对抗审查校正 - #92

Merged
Aqr-K merged 3 commits into
v3-pythonfrom
refactor/dispatch-unify-event-hardening
Jun 28, 2026
Merged

refactor(dispatch): 统一分发内核 + 事件广播并发加固(HIGH) + 对抗审查校正#92
Aqr-K merged 3 commits into
v3-pythonfrom
refactor/dispatch-unify-event-hardening

Conversation

@Aqr-K

@Aqr-K Aqr-K commented Jun 28, 2026

Copy link
Copy Markdown
Owner

概述

基于对 v3-python 近期已合并修复(#88 装配桥/渠道能力、#89 begin 限流、#91 速赢)的对抗式复核,本 PR 交付一项架构债收敛(统一两套分发内核)+ 一个并发 HIGH 修复 + 数项审查校正。基于当前 v3-python,全量 1980 passed / 1 skipped / 0 failed

变更(3 提交)

1. fix(event) 广播/链式分发锁内快照 + 消费者兜底(HIGH)

__dispatch_broadcast_event不持锁直接迭代活字典 __broadcast_subscribers[etype].items(),而 add/remove_event_listenerself.__lock 下运行时增删同一字典(插件启停/热重载)。并发会触发 RuntimeError: dictionary changed size during iteration,逃出仅捕 Empty__broadcast_consumer_loop → 消费者线程死亡 → 广播永久停摆。

  • 广播与链式分发均改为锁内 list(...) 快照后再迭代(链式原推导式窗口更小但一并收口)。
  • 消费者循环新增 except Exception 兜底,单次分发异常不再杀死消费者线程。
  • 新增 tests/test_event_broadcast_concurrency.py(2 例,RED→GREEN)。

2. fix(security/plugin) 对抗审查校正

  • CWE-208 计时侧信道:新增 security.compare_secrethmac.compare_digest),统一替换 4 处明文 != token 比较(security.__verify_keyanthropic/openai check_authsubscribe /seerr webhook)。
  • 模块默认优先级哨兵 100→9999 + 取值约束注释,补混排排序集成测试(锁定 priority=0 恒先于默认值)。
  • plugin_manager auth 域注册整体 try 隔离(原无条件 import 会让单域故障中断全部插件注册,且与 _unregister 不对称)+ 渠道能力静默跳过补 debug 诊断日志。

3. refactor(dispatch) 统一两套分发内核(架构债 #32+#24+#60

ChainBase(广播:插件面+系统面)与门面 Managers(单面/两步)原各自复刻同一套"按方法名遍历后端→合并规则累积→隔离错误/限流"逻辑(叠加 sync/async 双轨)。

  • 抽出单一真源 app/core/dispatch.py模块级函数,规避 ABCMeta vs Singleton 元类冲突),两侧改为组合委托的薄包装:chain/__init__.py −73 行、managers/base.py −43 行。
  • 合并规则逐字保持(空→取/系统面 check_signature 精化/list→extend/非空标量→短路)。
  • 精确保留 by-design 差异:chain 向系统后端透传 raise_exception(领域方法经签名消费),门面 pop 不透传——有铁证测试(严格形参后端:门面返 ok / chain 抛 TypeError)。
  • 顺带消除 chain 系统面双重日志。
  • 新增 tests/test_dispatch_kernel_unify.py(23 例:合并规则/错误隔离/限流/sync+async/透传差异)。

测试计划

  • 全量 pytest tests/1980 passed / 1 skipped / 0 failed
  • test_dispatch_kernel_unify.py(23 例,含 raise_exception 透传差异非空断言)
  • test_event_broadcast_concurrency.py(2 例)
  • 既有 test_*_facade.py 门面==run_module 等价测试不变通过

#90 的关系

本 PR 的计时侧信道修复触及 security.__verify_keyanthropic/openai/subscribe,与 OPEN 的 #90(API_TOKEN 降权,改 __get_api_token/服务 token payload)位于不同函数,无逻辑冲突,合并顺序无关。#90 的 BREAKING 降权由其自身承载,本 PR 无破坏性变更

遗留待办(不在本 PR,建议另开)

🤖 Generated with Claude Code

Aqr-K added 3 commits June 28, 2026 08:55
__dispatch_broadcast_event 旧实现不持锁直接迭代 __broadcast_subscribers 活字典,
运行时插件启停/热重载经 add/remove_event_listener 并发改字典 → RuntimeError:
dictionary changed size during iteration → 逃出 __broadcast_consumer_loop(仅捕 Empty)
→ 消费者线程死亡 → 广播永久停摆。

- 广播与链式分发均在 self.__lock 内对订阅者快照(list(...))后再迭代/过滤
- 消费者循环新增 except Exception 兜底,单次分发异常不杀死消费者线程
- 新增 tests/test_event_broadcast_concurrency.py 覆盖两条路径
据 5 路对抗审查综合裁决修正最近修复遗留问题:

- CWE-208 计时侧信道(HIGH):新增 security.compare_secret(hmac.compare_digest),
  统一替换 4 处明文 != 比较(security.__verify_key、anthropic/openai check_auth、
  subscribe /seerr webhook),消除 token 比较时序泄露
- 模块默认优先级哨兵 100→9999 并补取值约束注释(须 > 所有内建优先级,当前最大 10),
  补混排排序集成测试锁定 priority=0 恒先于默认值
- plugin_manager auth 域注册整体 try 隔离(import/注册失败不再波及契约域/通知域,
  与 unregister 对称)+ 渠道能力静默跳过补 debug 诊断日志

全量 1965 passed / 1 skipped。遗留待办(不阻断):XFF/proxy_headers 限流盲区、
access-token 与 flow 限流器预算翻倍、@cached 服务 token de-auth 窗口——另开 PR。
ChainBase(广播:插件面+系统面) 与 ManagerBase 系(门面:单面/两步) 原各自复刻同一套
"按方法名遍历后端→合并规则累积→隔离错误/限流" 逻辑(叠加 sync/async 双轨)。抽出
单一真源 app/core/dispatch.py(模块级函数,规避 ABCMeta vs Singleton 元类冲突),两侧
改为组合委托的薄包装。

- app/core/dispatch.py(+128): is_valid_empty / execute_modules / async_execute_modules,
  合并规则逐字保持(空→取/系统面 check_signature 精化/list→extend/非空标量→短路),
  错误与限流经回调注入,kwargs 原样转发(对控制位无主张)
- app/chain/__init__.py(-73)、app/managers/base.py(-43):__execute_*/_dispatch_* 委托内核
- 精确保留 by-design 差异:chain 向系统后端透传 raise_exception(不 pop),门面 pop 不透传
- 顺带消除 chain 系统面双重日志(__handle_system_error 内已记一次)
- 新增 tests/test_dispatch_kernel_unify.py(23 例):合并规则/错误隔离/限流/sync+async +
  raise_exception 透传差异铁证(chain 收到、门面 assertNotIn、严格形参后端证 pop 必要性)

全量 1988 passed / 1 skipped / 0 failed(基线 1965 + 23)。facade 等价测试不变通过。
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant