PyJHora 只载入一次、常驻复用 #131

Closed
opened 2026-10-28 06:02:39 +08:00 by Claude · 2 comments
Collaborator

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

问题

#93 把 PyJHora 装进生产后,BUG-1333/1334 的「导入不了就不起子进程」省法失效:每份报告起 5 次子进程(年度回放、Tajika、年度方法 worker),每次重新 import jhora,估多 5~10 s;worker 起之前也不查 jhora 在不在。

改法

放在新模块里起一个常驻 PyJHora 子进程(每次调用前显式重设岁差),按请求哈希缓存;worker 先查 find_spec。jyotish_api_server.py 不增长。

验收标准

屏蔽 / 不屏蔽 PyJHora 两种口径输出逐字节相同;一份报告的 subprocess.run 从 5 次降到 0~1 次;全量 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 代码体检(体检第 4 条),清单第 12 单。**由 Claude 直接实现,不交 Grok。** ## 问题 #93 把 PyJHora 装进生产后,BUG-1333/1334 的「导入不了就不起子进程」省法失效:每份报告起 5 次子进程(年度回放、Tajika、年度方法 worker),每次重新 import jhora,估多 5~10 s;worker 起之前也不查 jhora 在不在。 ## 改法 放在新模块里起一个常驻 PyJHora 子进程(每次调用前显式重设岁差),按请求哈希缓存;worker 先查 `find_spec`。`jyotish_api_server.py` 不增长。 ## 验收标准 屏蔽 / 不屏蔽 PyJHora 两种口径输出逐字节相同;一份报告的 `subprocess.run` 从 5 次降到 0~1 次;全量 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:41 +08:00
Author
Collaborator

@jesse 这张单我做完试验后没有推上去:按单子写的做法(PyJHora 常驻一个子进程反复用)会让一部分盘的结果变掉,而且也没变快。需要你定下一步。

我在本机装了和正式环境同版本的 PyJHora(4.8.7)实测:

1. 一份报告其实只起 1 次 PyJHora 子进程,不是 5 次。 冷生成一份完整报告共起 4 个子进程、合计 8.5 秒:

  • 年度方法 PyJHora 子进程:4.4 秒(这是本单要动的那个)
  • VedAstro 官方快照:4.0 秒(与 PyJHora 无关)
  • 两个只要 0.03 秒的小脚本

体检说的「年度回放、Tajika 也各起一次」,在产品调用里其实不起(只有研究用途才起),所以「5 次降到 0~1 次」这个目标本身估多了。

2. 常驻子进程会改结果。 12 张虚构盘按顺序算(四种岁差轮着来),常驻子进程和「每次新起一个」相比,有 3 张盘的年度方法结果不同,正好是三张 true_citra 岁差的盘。原因是 PyJHora 有进程级的全局状态:前一张盘用过别的岁差后,即使代码每次都重新设置岁差,true_citra 也算不回原样。这正是当初要每次单独起子进程的原因。「每次新起」本身是稳定的(连跑两遍完全一样)。

3. 也没变快。 同样 12 张盘,常驻 96.9 秒,每次新起 80.2 秒。时间主要花在 PyJHora 计算本身,载入只占很小一部分。

所以试验代码我已经撤掉,没有进 staging。

你选:

  • A(推荐):这张单按「不做」关掉,保留每次单独起子进程(结果最稳)。
  • B:改成把年度方法这一章的结果按「出生资料 + 岁差 + 年份 + PyJHora 版本」存进只有本机能读的磁盘缓存。同一张盘重新生成报告,或者部署之后再生成,能省下这 4.4 秒;结果和现在逐字节相同。这是另一张小单。
  • C:继续常驻,但每次换岁差就重启子进程。复杂,省得也少,我不推荐。
<!-- agent:claude escalate --> @jesse 这张单我做完试验后**没有推上去**:按单子写的做法(PyJHora 常驻一个子进程反复用)会让一部分盘的结果变掉,而且也没变快。需要你定下一步。 我在本机装了和正式环境同版本的 PyJHora(4.8.7)实测: **1. 一份报告其实只起 1 次 PyJHora 子进程,不是 5 次。** 冷生成一份完整报告共起 4 个子进程、合计 8.5 秒: - 年度方法 PyJHora 子进程:4.4 秒(这是本单要动的那个) - VedAstro 官方快照:4.0 秒(与 PyJHora 无关) - 两个只要 0.03 秒的小脚本 体检说的「年度回放、Tajika 也各起一次」,在产品调用里其实不起(只有研究用途才起),所以「5 次降到 0~1 次」这个目标本身估多了。 **2. 常驻子进程会改结果。** 12 张虚构盘按顺序算(四种岁差轮着来),常驻子进程和「每次新起一个」相比,有 3 张盘的年度方法结果不同,正好是三张 `true_citra` 岁差的盘。原因是 PyJHora 有进程级的全局状态:前一张盘用过别的岁差后,即使代码每次都重新设置岁差,`true_citra` 也算不回原样。这正是当初要每次单独起子进程的原因。「每次新起」本身是稳定的(连跑两遍完全一样)。 **3. 也没变快。** 同样 12 张盘,常驻 96.9 秒,每次新起 80.2 秒。时间主要花在 PyJHora 计算本身,载入只占很小一部分。 所以试验代码我已经撤掉,没有进 staging。 你选: - **A(推荐)**:这张单按「不做」关掉,保留每次单独起子进程(结果最稳)。 - **B**:改成把年度方法这一章的结果按「出生资料 + 岁差 + 年份 + PyJHora 版本」存进只有本机能读的磁盘缓存。同一张盘重新生成报告,或者部署之后再生成,能省下这 4.4 秒;结果和现在逐字节相同。这是另一张小单。 - **C**:继续常驻,但每次换岁差就重启子进程。复杂,省得也少,我不推荐。
Claude added agent/需拍板 and removed agent/排队 labels 2026-10-28 13:11:10 +08:00
Owner

不做

不做
jesse closed this issue 2026-10-28 13:24:48 +08:00
Sign in to join this conversation.
2 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: root/Jyotisha#131