diff --git a/docs/scheduler-mechanism.md b/docs/scheduler-mechanism.md new file mode 100644 index 00000000..5658d91f --- /dev/null +++ b/docs/scheduler-mechanism.md @@ -0,0 +1,39 @@ +# MoFin 定时任务调度机制(2026-08-20 补记) + +> 目的:之前"改每日重评时间 15 分钟没搞定、错过 7:10"——根因是没有文档说明 hermes cron 调度机制。本文件记录,避免后人(含 AI)再踩坑。 + +## 一、调度源在哪 +- **唯一权威**:`~/.hermes/profiles/position-analyst/cron/jobs.json` +- 每个任务有 `schedule` 对象:`{"kind": "cron", "expr": "10 7 * * 1-5", "display": "..."}` +- `schedule.expr` = cron 表达式(**这是决定运行时间的唯一字段**) + +## 二、改时间的正确方法(只改一处!) +**只需改 `schedule.expr`**(比如 8:10 → 7:10): +```json +"schedule": { "kind": "cron", "expr": "10 7 * * 1-5", "display": "10 7 * * 1-5" } +``` +- `schedule_display`(顶层)也要同步改(仅显示用) +- **不需要改 `next_run_at`**——调度器(hermes cron)每次 tick 用 **croniter** 基于 `expr` **自动重算** next_run_at +- `next_run_at` 是**派生显示值**,不是事实来源,改了反而可能被覆盖 + +## 三、调度器机制(hermes cron) +- 源码:`/home/hmo/hermes-agent/cron/jobs.py`(`parse_schedule` 用 croniter 解析)、`hermes_cli/cron.py`(`cron_tick`) +- **每次 tick 重新 `load_jobs()` 读 jobs.json**(jobs.py:426) +- 有**自动修复逻辑**(jobs.py:444):jobs.json 被直接编辑后,tick 时检测并重算 next_run +- 手动触发:`hermes_cli.main -p position-analyst cron tick` +- **结论:改 expr 后,等调度器下一次 tick 即生效,无需重启服务** + +## 四、调度器进程 +- position-analyst 的 cron 由 `hermes-gateway-zhiwei.service` 托管(systemd) +- `ps aux | grep hermes` 可见 `hermes_cli.main -p position-analyst gateway run --replace` + +## 五、踩坑教训(2026-08-20) +1. **只改 expr 即可**,别动 next_run_at(派生值,会被重算覆盖) +2. 之前我改了 expr 又去改 next_run_at/cron.db(cron.db 是空的!)——**都是多余的**,浪费了 15 分钟 +3. **调度时间不是散落多处**——它单一在 jobs.json 的 schedule.expr。之前以为要改多处(expr/display/next_run/cron.db)是**对机制不理解**,不是架构冗余 + +## 六、每日盘前重评(预盘全量) +- 任务:`premarket_full_review.py`,调度 `10 7 * * 1-5`(7:10,2026-08-20 改) +- 作用是第 4 类重评:①regenerate_all 技术重评 ②batch_reassess 持仓+自选 12 维 LLM(后台)③自选退出 +- 后台 12 维日志:`/tmp/holdings_12d_daily.log` +- 结果摘要:`/tmp/mofin_premarket/summary.json`