← 精品代码功能 · 可复用实现库

精品功能 09:定时任务幂等守卫(多触发 + 两处证据)

\+ install_task.bat / run_daily.bat

如果只注册一个时间点,电脑那时没开机就永远不跑。但多注册几个触发点,
又可能重复执行、重复花钱。

核心实现

多触发点 + 守卫(install_task.bat 注册早/晚/开机后三个任务;
每次执行先问守卫):

def already_done_today() -> tuple[bool, str]:
    """今天是否**完整**跑过一轮,返回 (是否完成, 说明)。

    "完整" = 抓取和日报两件都做了。只做了一半(比如抓完中途挂了)不算完成 ——
    否则晚上那次重试就被自己挡掉了,而那正是最需要它的时候。

    判断用的是两处独立证据,不猜:
      - runs 表今天的记录  → 抓取成功了
      - 今天的 digest 文件 → 日报生成成功了
    """
    fetched = _fetched_today()
    digested = _digested_today()
    if fetched and digested:
        return True, "今天已完成(抓取 + 日报都在)"
    missing = []
    if not fetched:
        missing.append("抓取")
    if not digested:
        missing.append("日报")
    return False, "今天还缺:" + "、".join(missing)

可观测性(为什么需要 health,第 556-561 行的注释):

"""体检:一条命令回答「它到底在正常跑吗」。
存在的理由很具体:定时任务没生效时,系统不会有任何报错 ——
它只是安静地什么都不做。没有这个命令,只能靠"感觉最近没收到日报"来发现。"""

设计亮点

  1. 多触发点解决"错过不补跑":早/晚/开机后都注册,谁先跑谁干活
  2. 幂等守卫:--skip-if-done + already_done_today(),重复触发无害
  3. 两处独立证据:数据库记录 + 文件存在,比"一个标志位"可靠(标志位写到一半崩溃就坏了)
  4. "完整"的定义很讲究:抓取和日报都完成才算完成,半途而废能被晚场重试救回
  5. 显式体检命令:解决"静默失败"——没报错不等于在跑
  6. 纯 ASCII + CRLF 的 bat:中文 Windows 代码页的坑,被测试钉死(见第 19 课)

可复用性评估

开源化建议

对照开源

解决的是"进程没起来时也要能补跑"的问题——两者互补

相关课程

第 12 课(工程化)、第 17 课(数据流水线)