# 2026-07-03 — work #01: market-sync.service 2h timeout 截断同步 ## 发现 跑 `bin/daily_sync_check.py --report-only`(周五 10:31)→ 10 个 missed: ``` ❌ stock_basic / kline_daily / kline_index / kline_5min / tick_trade ❌ moneyflow / industry_sector / sector_features / market_regime / longhubang ✅ share_snapshot (今日 00:03:01 手动跑过) ⏸ stock_node (周末专属任务,今天周五不期望) ``` ## 根因 不是今天调度出问题,是**昨天 2026-07-02 15:30 runall 没跑完**: ``` 15:30:01 启动 runall 15:38:50 stock_basic 完成 (529s) 15:38:58 kline_index 完成 (2s) 15:56:54 kline_daily 完成 (1072s) warning 17:06:09 kline_5min 完成 (4150s=69min) ← 单 task 吃掉一半窗口 17:22:37 industry_sector 完成 (983s) warning (baostock timeout) 17:24:27 sector_features 完成 (105s) 17:24:32 >>> 开始 share_snapshot 17:30:01 systemd SIGTERM 杀进程 ← TimeoutStartSec=7200 (2h) 到期 ✗ share_snapshot 没跑 ✗ market_regime 没跑 ``` 后果链: 1. 昨天 kline_5min 全量同步 5207 只耗时 69 min(4150s),单 task 吃掉 1/2 窗口 2. industry_sector 又因 baostock connection timed out 浪费 16 min 3. 17:30 systemd timeout 砍掉 share_snapshot + market_regime 4. 今天 09:00 该跑的 stock_basic 没跑 —— 因为 worker.py 没长驻 + market-sync.timer 只在 15:30 触发 5. tick/moneyflow/lhb 几个独立 timer 在 21:05/21:35/22:00 跑过但今天又没补 ## 解决 ### 短期(本次 commit) - `bin/systemd/market-sync.service`: `TimeoutStartSec` 从 `7200` (2h) 提到 `14400` (4h) - 注释 `实际 ~80min` → 改成 `~80min + kline_5min 增量 70min, 总 ~2.5h, 留 buffer` - 加 `bin/systemd/market-sync-daily-check.timer` + `.service` - 每天 23:00 跑 `bin/daily_sync_check.py`,替代 `/loop` 方案的 session-only 限制 ### 中期(不在本次 commit,记录备查) - kline_5min 改成增量模式(当前是全量 5207 只每次),预计从 69min 降到 5min - 增量条件:`bar_time >= 上次同步时间 - 1 天`(含补漏) - worker.py 长驻 + 进程内 scheduler 接管盘后 task 调度,与 systemd timer 二选一([[dual-scheduler-overlap]]) - 失败 task 自动 retry 一次(仅 failed,不 retry partial-success / warning) ### 长期(架构改进) - runall 拆成 fast-path / slow-path 两个 service: - fast-path: stock_basic / kline_index / kline_daily / industry_sector / share_snapshot / market_regime(~30min) - slow-path: kline_5min 全量(独立 timer @ 周日凌晨,避免挤占交易日窗口) ## 关联 - [[background-watcher-pitfalls]]: "不要让 systemd TimeoutStartSec= 自动收尾" - 实际情况是 runall 卡在 kline_5min,wrapper 的 fast-poll 也没起到作用(runall 在 2h 内确实没退出,systemd 超时是对的) - [[dual-scheduler-overlap]]: worker.py 没运行 → 完全依赖 systemd timer - [[market-data-overview]]: 任务耗时分布 ## 验收 commit 后验证: ```bash sudo cp bin/systemd/market-sync.service /etc/systemd/system/ sudo cp bin/systemd/market-sync-daily-check.{service,timer} /etc/systemd/system/ sudo systemctl daemon-reload sudo systemctl restart market-sync.timer systemctl status market-sync-daily-check.timer # 等今晚 23:00 看 daily_check 报告 ```