Skip to content

refactor(registry): schema 建表/迁移与 get_connection 解耦为显式生命周期步骤 | decouple schema init/migration from get_connection #85

Description

@370025263

背景

这是 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:使用旧库运行新代码时,迁移仅执行一次,且由预期的进程执行。

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions