同一个 Python 文件只载入一份 #132

Open
opened 2026-10-28 06:02:43 +08:00 by Claude · 3 comments
Collaborator

来自 #118 代码体检(体检第 20 条),清单第 13 单。由 Claude 直接实现,不交 Grok。

问题

jyotish_api_server._load_local_module 用 _jyotish_local_<name> 另起一份模块,加上 scripts.X / X 两种 import:一次咨询 + 一次排盘后 20 个模块重复载入(引擎 3 份),各份的缓存互不相通。

改法

加载器先查 sys.modules 里已有的同一文件,有就复用;只改加载器,不动调用点。

验收标准

重复载入 20 → 0(测试断言);增长护栏不涨;全量 pytest 与基线失败清单一致。

规矩

  • 基于 origin/staging,独立工作树 codex/*;只改这一件事。
  • BUG 号开工时按 docs/BUG_HISTORY.md 全文件取最大号 +1。
  • 同时改 frontend/src/app/(app)/page.tsx 的单按清单顺序串行。
  • 体检报告:docs/research/code_health_audit_2026_10_28.md(staging a31b6dda3)
来自 #118 代码体检(体检第 20 条),清单第 13 单。**由 Claude 直接实现,不交 Grok。** ## 问题 `jyotish_api_server._load_local_module` 用 `_jyotish_local_<name>` 另起一份模块,加上 `scripts.X` / `X` 两种 import:一次咨询 + 一次排盘后 20 个模块重复载入(引擎 3 份),各份的缓存互不相通。 ## 改法 加载器先查 `sys.modules` 里已有的同一文件,有就复用;只改加载器,不动调用点。 ## 验收标准 重复载入 20 → 0(测试断言);增长护栏不涨;全量 pytest 与基线失败清单一致。 ## 规矩 - 基于 origin/staging,独立工作树 `codex/*`;只改这一件事。 - BUG 号开工时按 `docs/BUG_HISTORY.md` 全文件取最大号 +1。 - 同时改 `frontend/src/app/(app)/page.tsx` 的单按清单顺序串行。 - 体检报告:`docs/research/code_health_audit_2026_10_28.md`(staging `a31b6dda3`)
Claude added the agent/试点agent/排队 labels 2026-10-28 06:02:48 +08:00
Author
Collaborator

已改完,推上 staging 8a72aa5b(同一批的最后一张),正在部署。

  • 排盘服务的加载器以前会给同一个计算文件另起一份私有副本;现在先看已经载入的那份,有就直接用,没有就按普通名字载入,之后别处也拿到同一份。97 个调用点都没动。
  • 实测(一次咨询 + 一次排盘):加载器造出来的副本 19 → 0(单子写的约 20)。还剩 19 份重复,是代码里 scripts.X 和 X 两种普通写法各 import 了一次,跟加载器无关,不在本单范围;需要的话另开单收。
  • 检查:凡用到加载器或计算服务的 41 个测试文件,改前改后各跑一遍,失败清单完全一样(只有一条在 staging 上本来就失败);新增 3 条测试,放到改前代码上会失败。主文件增长护栏通过。记为 BUG-1482。
  • 这样改完,模块都能按名字被子进程找到,#133 多进程要用。不需要真机看。
<!-- agent:claude review sha=8a72aa5b verdict=pass staging=8a72aa5b446cf20271cbce715bde75a021682f7e checklist=- --> 已改完,推上 staging `8a72aa5b`(同一批的最后一张),正在部署。 - 排盘服务的加载器以前会给同一个计算文件另起一份私有副本;现在先看已经载入的那份,有就直接用,没有就按普通名字载入,之后别处也拿到同一份。97 个调用点都没动。 - 实测(一次咨询 + 一次排盘):加载器造出来的副本 19 → 0(单子写的约 20)。还剩 19 份重复,是代码里 `scripts.X` 和 `X` 两种普通写法各 import 了一次,跟加载器无关,不在本单范围;需要的话另开单收。 - 检查:凡用到加载器或计算服务的 41 个测试文件,改前改后各跑一遍,失败清单完全一样(只有一条在 staging 上本来就失败);新增 3 条测试,放到改前代码上会失败。主文件增长护栏通过。记为 BUG-1482。 - 这样改完,模块都能按名字被子进程找到,#133 多进程要用。不需要真机看。
Claude added agent/部署中 and removed agent/排队 labels 2026-10-28 12:45:50 +08:00
Author
Collaborator

@jesse 说明一个我造成的问题:这张单的改动让 staging 门禁(run 5888)失败了,已修好,推上 staging a614895a,正在重新跑门禁。

  • 出了什么问题:合盘全档案会用两个线程同时算两个人的盘。改动后,第二个线程可能拿到第一个线程「还没载入完」的计算代码,于是报错。正式环境没受影响,因为门禁拦住了,没有部署出去。
  • 怎么修的:复用已经载入的代码时,先等它载入完再用。
  • 验证:本机按门禁同一段代码构造合盘全档案,修前 4 次都报同一个错,修后 6 次都通过;门禁里失败的那条前端测试本机也通过(17 条全过)。新增 1 条测试:4 个线程同时载入,修前有 1 个拿到半成品,修后全对。
  • 为什么当时没拦住:本机全量前端测试里这条一直失败(本机系统自带的 Python 没装排盘库),我把它当成「本来就失败」比对掉了。已写进错误台账(ERR-117),以后本机跑前端测试时会让它用项目自己的 Python。BUG-1482 已补记这次复发。

这一批(#127、#130、#132、#138、#139,以及别的会话的 #141)都等这次门禁过了一起部署,部署好了我再说。

<!-- agent:claude review sha=a614895a2b77d154830d830fdec333ac3fe1d239 verdict=pass staging=a614895a2b77d154830d830fdec333ac3fe1d239 checklist=- --> @jesse 说明一个我造成的问题:这张单的改动让 staging 门禁(run 5888)失败了,已修好,推上 staging `a614895a`,正在重新跑门禁。 - **出了什么问题**:合盘全档案会用两个线程同时算两个人的盘。改动后,第二个线程可能拿到第一个线程「还没载入完」的计算代码,于是报错。正式环境没受影响,因为门禁拦住了,没有部署出去。 - **怎么修的**:复用已经载入的代码时,先等它载入完再用。 - **验证**:本机按门禁同一段代码构造合盘全档案,修前 4 次都报同一个错,修后 6 次都通过;门禁里失败的那条前端测试本机也通过(17 条全过)。新增 1 条测试:4 个线程同时载入,修前有 1 个拿到半成品,修后全对。 - **为什么当时没拦住**:本机全量前端测试里这条一直失败(本机系统自带的 Python 没装排盘库),我把它当成「本来就失败」比对掉了。已写进错误台账(ERR-117),以后本机跑前端测试时会让它用项目自己的 Python。BUG-1482 已补记这次复发。 这一批(#127、#130、#132、#138、#139,以及别的会话的 #141)都等这次门禁过了一起部署,部署好了我再说。
Author
Collaborator

@jesse 已部署到 staging(线上版本 a614895a,前端和排盘服务都是这一版;门禁、数据库迁移、部署三步都成功,登录页 200、未登录读账户 401 正常)。

不需要真机看;这次门禁里合盘全档案那条测试已通过。

没问题请关单,有问题直接在这里说。

<!-- agent:claude deployed sha=a614895a2b77d154830d830fdec333ac3fe1d239 --> @jesse 已部署到 staging(线上版本 `a614895a`,前端和排盘服务都是这一版;门禁、数据库迁移、部署三步都成功,登录页 200、未登录读账户 401 正常)。 不需要真机看;这次门禁里合盘全档案那条测试已通过。 没问题请关单,有问题直接在这里说。
Claude added agent/待真机 and removed agent/部署中 labels 2026-10-28 14:12:00 +08:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: root/Jyotisha#132