背景
这是 PR #83 review 遗留的议题。目前,registry 的 schema 建表和 _migrate 迁移由 get_connection 触发,即“首次调用时自动建表”。原因是 registry 没有统一的初始化入口:server、各 CLI 子命令、watcher、dashboard 和测试都可能率先访问 registry.db,而它们唯一的公共调用路径是获取连接。
#83 已将该检查优化为 O(1):将 schema 内容的 CRC32 指纹存入 PRAGMA user_version,指纹一致时直接跳过。然而,“获取连接”与“schema 生命周期管理”之间的职责耦合仍然存在。
问题
- 职责不清:连接获取函数同时负责执行 DDL 和迁移;
_migrate 的唯一调用点隐藏在 get_connection 中,迁移逻辑缺少独立、明确的入口。
- 迁移时机不可控:升级后,首个访问 DB 的进程会执行迁移。它可能只是一个短生命周期的 CLI 命令,却需要承担 recommendation_log 去重等耗时数分钟的一次性历史回填。
- 并发首开缺少互斥:多个进程同时首次打开旧库时,会分别执行一遍建表和迁移。DDL 具有幂等性,因此不会造成破坏;但一次性回填类迁移仍依赖幂等写法,缺少结构性保障。
提议
- 新增显式的
init_registry_db()(命名待定),作为建表和迁移的唯一入口。
- 在明确的生命周期节点调用:
serve 启动序列、CLI 公共入口前置阶段和测试 fixture。
- 将
get_connection 简化为纯连接获取函数;schema 未就绪时立即报错,而不是静默补建。
- 为迁移执行增加进程间互斥,例如使用
BEGIN IMMEDIATE 或 DB 级 advisory lock。
时机
建议与 openspec/backend-slow-resilience(#76)的 server 启动序列改造合并实施,避免重复调整启动链路。
验收
get_connection 不再包含 executescript 或 _migrate。
- 所有入口(serve、CLI、watcher、测试)在 schema 未初始化时均有明确的报错路径。
- 覆盖升级场景的 e2e:使用旧库运行新代码时,迁移仅执行一次,且由预期的进程执行。
背景
这是 PR #83 review 遗留的议题。目前,registry 的 schema 建表和
_migrate迁移由get_connection触发,即“首次调用时自动建表”。原因是 registry 没有统一的初始化入口:server、各 CLI 子命令、watcher、dashboard 和测试都可能率先访问registry.db,而它们唯一的公共调用路径是获取连接。#83 已将该检查优化为 O(1):将 schema 内容的 CRC32 指纹存入
PRAGMA user_version,指纹一致时直接跳过。然而,“获取连接”与“schema 生命周期管理”之间的职责耦合仍然存在。问题
_migrate的唯一调用点隐藏在get_connection中,迁移逻辑缺少独立、明确的入口。提议
init_registry_db()(命名待定),作为建表和迁移的唯一入口。serve启动序列、CLI 公共入口前置阶段和测试 fixture。get_connection简化为纯连接获取函数;schema 未就绪时立即报错,而不是静默补建。BEGIN IMMEDIATE或 DB 级 advisory lock。时机
建议与 openspec/backend-slow-resilience(#76)的 server 启动序列改造合并实施,避免重复调整启动链路。
验收
get_connection不再包含executescript或_migrate。