Files
Jyotisha/docs/tasks/PROGRESS-api-chart-subprocess-gate-20261013.md
T
jesse-uxGrok (agent loop)Cursor
336286e428 fix(chart): skip unused synastry overview and doomed report subprocesses
Synastry charts now skip the unused external overview and run together. Reports skip PyJHora subprocesses when that library is missing, and a full heavy-compute slot logs which paths hold it. Splitting quotas stays a simulation.

Gate, growth, and report pytest passed, as did the frontend route tests, tsc, lint, and the A/B script.

Co-Authored-By: Grok (agent loop)
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-15 08:02:39 +08:00

5.3 KiB
Raw Blame History

PROGRESS · 合盘排盘与报告多余子进程(2026-10-15)

  • 分支:codex/api-chart-subprocess-gate-20261013
  • 实际基线:origin/staging 9274491681f6fcacbc87e3797441d2c5221de874(任务书写的 77057a819 更早)
  • scripts/jyotish_api_server.py:开工 10944 行,做完 10940 行
  • BUG-1333、BUG-1334。docs/BUG_HISTORY.md 后半是同一份历史的副本,两处都补上了。

做了什么

  1. 合盘两次排盘都带 skip_vedastro_main_entry_overview: true,不改 synastryBirthPayload。两张盘和婚恋分支的两张九分盘都改成同时发出。任一失败仍走原来的 catch。
  2. 前端 app/api 和 lib 里发往 /api/chart 的请求体必须带这个开关。白名单是空的。
  3. 父进程先看一次能不能导入 PyJHora。不能就不起年度回放和 Tajika 的子进程,返回和「子进程在没装时」相同的结果。样本在 tests/fixtures/api-chart-subprocess-gate/,来自本机真实子进程(当时 find_spec("jhora") 为 None)。装了之后仍走子进程。
  4. 解释器查找(含「没找到」)和静态 oracle 校验在进程内各记一次。校验按文件路径、mtime、大小作键。不缓存出生资料。
  5. 开关 JYOTISH_GATE_CHART_OVERVIEW 默认关。只有把它设为 1 时,不带 skip、也不是异步排队的 /api/chart 才占一个重计算名额。/api/chart 没有加进 HEAVY_COMPUTE_PATHS。预热咨询不占名额的判断挪进了闸门模块。
  6. 名额占满时打一行日志:被拒路径、当前占用者路径、已占秒数。不写请求正文。

自测

检查 命令 结果
闸门、增长护栏、本单新测试 .venv\Scripts\python.exe -m pytest tests/test_api_chart_subprocess_gate.py tests/test_api_heavy_compute_gate.py tests/test_api_server_growth_contract.py -q 21 passed,退出码 0
报告三份既有测试 同上解释器 -m pytest tests/test_report_reader_main.py tests/test_report_longform_parity.py tests/test_report_density_facts.py -q 27 passed,退出码 0
前端本单与相关单文件 在 frontend 下 node node_modules/tsx/dist/cli.mjs --test tests/synastry-chart-skip.test.ts tests/chart-request-skip-contract.test.ts tests/chart-view-route.test.ts tests/ephemeris-route.test.ts 22 pass,0 fail
类型检查 frontend\node_modules\.bin\tsc --noEmit -p frontend 退出码 0
lint 在 frontend 下 npm run lint 退出码 0,0 error,123 条原有 warning
A/B .venv\Scripts\python.exe scripts\research\api_chart_subprocess_ab.py 退出码 0。数字见下

grep 这三个名字在 tests/ 里只命中本单新测试:annual_pyjhora_replay、_oracle_progress_snapshot、_resolve_external_pyjhora_python。

A/B 数字

合盘:串行不带 skip 中位 8.0596 秒、2 次 subprocess.run;并发带 skip 中位 0.0166 秒、0 次。盘面摘要逐字节一致。耗时约为对照的 0.2%。

报告:强制仍起子进程中位 16.5322 秒、7 次;短路后 15.3235 秒、1 次。去掉易变字段后逐字节一致。少掉的 6 次是年度回放和 Tajika。

名额模拟(种子 64,一分钟,未改规则):

方案 咨询被拒 报告被拒 校正被拒 最高并发 碰到不得加池的那条
O1 现状 40% 0% 17% 2 否
O2 咨询单独小池 0% 0% 17% 3 是
O3 咨询最多再等 1.5 秒 30% 0% 33% 2 否
O4 重任务最多占 1 个 0% 0% 67% 2 否

全文在 docs/testing/api-chart-subprocess-gate-ab-20261013.md。

改既有断言

无。原值 / 新值 / 原因:没有改旧断言。

偏离

  • /api/health 没有加 heavy_compute 字段。状态函数 heavy_compute_status() 在闸门模块里,接到健康检查会让主文件变长。任务书允许砍掉这一项。
  • 星盘名额开关默认关。打开会让不带 skip 的外部调用可能拿到 429,任务书要求先有 A/B 再提议,本单不打开。
  • O2、O3、O4 没有实现。
  • 报告对照不是 staging 源码另导入,而是本分支把「已安装」强制打开。静态校验缓存两边都在,所以耗时差只反映那 6 个子进程。
  • 合盘子进程是 2 → 0,不是任务书举例的 4 → 0。这台机器两张盘合计只数到 2 次 subprocess.run。
  • 没有「装了 PyJHora」的计时。父进程强制当成已安装时,子进程仍会因为没装而失败,这一组用来代表「不短路就要付启动开销」。

环境缺口

  • 本机 .venv:sys.executable 是工作树的 python.exe;shutil.which("python3") 是 Windows 应用商店占位;python3.14 没有;find_spec("jhora") 是 None。
  • Docker 在,没有本地 jyotisha-api 镜像,镜像里的解释器路径没有核实。
  • 生产装了 VedAstro、并且开了外网时,不带 skip 的排盘真实耗时本机测不到。
  • 名额被占满后连带拒绝的真实频率,要等日志上了 staging 再看。

需拍板

轻重任务要不要分开限流,本单不改。模拟里,让咨询少被拒,校正就会多被拒;给咨询单独开池会让同时在跑的个数超过 2。要改规则需要另立一单。

默认值

  • JYOTISH_GATE_CHART_OVERVIEW 默认关。
  • 合盘 skip 和报告短路没有开关。