Skip to content

fix(gateway): 修复批量更新 API 格式时的认证通道状态冲突 - #702

Merged
fawney19 merged 1 commit into
fawney19:mainfrom
MMEXA:fix/reconcile-auth-channel-mismatch-formats
Jul 31, 2026
Merged

fix(gateway): 修复批量更新 API 格式时的认证通道状态冲突#702
fawney19 merged 1 commit into
fawney19:mainfrom
MMEXA:fix/reconcile-auth-channel-mismatch-formats

Conversation

@MMEXA

@MMEXA MMEXA commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

问题背景

管理员在号池批量编辑中修改 api_formats 时,客户端只提交本次实际编辑的字段,不会重复提交隐藏的 allow_auth_channel_mismatch_formats。旧数据中如果仍保留已不属于新格式集合的值,更新构建器会把这份历史状态当作显式输入再次严格校验,导致整个批量操作返回 400,例如:

allow_auth_channel_mismatch_formats 包含未选择的 API 格式: openai:embedding

这会阻断本应合法的格式收窄操作,并且要求调用方了解和修复其未编辑的内部状态。

根因

密钥更新主链没有区分两种不同语义:

  1. 调用方显式提交 allow_auth_channel_mismatch_formats,此时必须严格验证其为已选 API 格式的子集;
  2. 调用方只修改 api_formats,此时历史 allowlist 属于待协调的既有状态,应随新的格式集合确定性收敛。

原实现对两种情况都调用严格校验,因此历史残留会把正常更新转换为配置错误。

修改内容

  • 在 provider write 的规范化模块中集中复用格式别名规范化与去重逻辑;
  • 显式提交 mismatch allowlist 时继续执行严格校验,非法输入仍返回 400;
  • 普通密钥仅修改 api_formats 且省略 mismatch 字段时,将历史 allowlist 与新的格式集合取交集;
  • 固定 OAuth Provider 的有效格式由 Provider endpoint 继承,更新构建器无法从 key 的空 api_formats 推导完整集合,因此保留其 allowlist,不按空集合误删;
  • 保持现有批量 staged-update 流程不变,任一显式配置非法时仍在持久化前整体失败,不产生部分写入。

行为契约

请求场景 结果
显式提交合法 mismatch allowlist 规范化、去重并保存
显式提交未选择的格式 返回 400,不写入
仅修改 api_formats 历史 allowlist 自动收敛为新格式集合的子集
固定 OAuth Provider 修改 key 格式 保留继承格式相关 allowlist

CI 稳定性

PR 首轮与重触发后的 Test (Workspace Rest) 都在同一条 usage runtime 并发测试中触发 2 秒超时。该测试使用 Notify::notify_waiters() 释放单个生命周期等待者;如果通知发生在等待 future 真正注册之前,通知不会保留 permit,测试会永久等待到超时。

本次同步修正不改变生产代码:

  • 单等待者释放改用会保留 permit 的 notify_one()
  • 复用可控写入测试存储,确定性建立“一个 seed 正在写入、一个 terminal 正在排队”的状态;
  • 逐笔释放写入,并核验两条实际持久化记录、完成计数、峰值 pending 与最终归零;
  • 保留原有并发契约强度,不通过延长超时或放宽断言规避竞态。

验证

  • cargo fmt --all -- --check
  • cargo clippy -p aether-gateway --lib --bins --examples -- -D warnings
  • cargo clippy -p aether-usage-runtime --all-targets -- -D warnings
  • RUST_MIN_STACK=16777216 cargo nextest run -p aether-gateway --lib -E 'test(gateway_batch_updates_shared_pool_key_configuration) | test(gateway_preserves_inherited_fixed_oauth_mismatch_formats_on_batch_update) | test(gateway_rejects_explicit_invalid_mismatch_format_without_writing_any_key) | test(reconcile_allow_auth_channel_mismatch_formats_keeps_only_selected_formats)' --no-fail-fast
  • cargo nextest run -p aether-usage-runtime -E 'test(awaited_terminal_does_not_hold_permit_behind_queued_terminal_seed) | test(submitted_terminal_does_not_hold_permit_behind_queued_terminal_seed)' --no-fail-fast

聚焦结果:gateway 4 个测试与 usage runtime 2 个测试全部通过。覆盖普通密钥的交集收敛与空交集、显式非法配置的错误文本和零写入、固定 OAuth Provider 的继承格式保留,以及两种 terminal 提交模式下的确定性并发排队与完整持久化。

@MMEXA
MMEXA force-pushed the fix/reconcile-auth-channel-mismatch-formats branch from 9adcd1b to b738bbc Compare July 30, 2026 13:56
@MMEXA
MMEXA force-pushed the fix/reconcile-auth-channel-mismatch-formats branch from b738bbc to 6ecfe0f Compare July 30, 2026 14:14
@fawney19
fawney19 merged commit 6688ee2 into fawney19:main Jul 31, 2026
22 checks passed
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.

2 participants