Files
market_sync/docs/works/2026-07-03-01-market-sync-timeout.md
gao 295177027f fix: market-sync 2h timeout 截断 + 加 daily-check 巡检
work #01 (2026-07-03):昨天 15:30 runall 中 kline_5min 全量 69min 把 2h
窗口吃满,share_snapshot / market_regime 被 systemd SIGTERM 截断;
今天又叠加 worker.py 未长驻,导致 10 个 task missed。

变更:
- bin/systemd/market-sync.service: TimeoutStartSec 7200 → 14400 (4h)
- bin/daily_sync_check.py: 新增每日巡检,读 PG dataset_registry,
  对比 SCHEDULE 判定 ok/missed/failed/stuck/never_run,写 JSON 报告,
  失败时 POST HMAC webhook
- bin/systemd/market-sync-daily-check.{service,timer}: 23:00 daily 触发
  daily_check(替代 session-only 的 /loop 方案)
- config/daily_check_secrets.env.template: webhook 配置模板
- docs/works/2026-07-03-01-market-sync-timeout.md: 完整 work 记录
  (根因 + 中期/长期改进建议)

Co-Authored-By: Claude <noreply@anthropic.com>
2026-07-03 10:48:20 +08:00

78 lines
3.3 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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 min4150s),单 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_5minwrapper 的 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 报告
```