"""一个可以直接用的常驻任务模块(CLI 的 ``--tasks`` 就指向它)。 它是给命令行用的示例模块,也是你自己模块的模板。用法:: PYTHONPATH=examples uv run chongming-task --db ./tasks.db \ run --tasks worker_tasks consume --arg source=kafka://orders --task-id orders-worker ## 三件必须做对的事 1. **每轮调 ``ctx.checkpoint()``**——停止是协作式的,不调用它就停不掉(会落 ``lost``)。 2. **用 ``ctx.is_stop_requested`` 收尾**——这样任务终态是 ``succeeded``,返回值保留; 让 ``checkpoint()`` 抛则是 ``stopped``、无返回值。 3. **进度按批次上报,不要每条一次**——``ctx.progress()`` 每次都要取运行锁,它是给 "人看得懂"的频率设计的。 """ from __future__ import annotations import time from typing import Any from chongming_task import RetryPolicy, task @task(tags={"kafka"}, retry=RetryPolicy(max_attempts=1)) def consume(ctx: Any, source: str, batch: int = 1000) -> int: """常驻消费 source;收到停止请求后收尾并返回本次共处理多少条。""" ctx.log(f"开始消费 {source}") total = 0 while not ctx.is_stop_requested: ctx.checkpoint() # 假装取了一批消息。真实实现里这里是一次 poll / 一次拉取。 time.sleep(0.05) total += batch # 按批次上报进度(不是每条一次)。 ctx.progress(total, unit="msg", message=source) ctx.log(f"收到停止请求,收尾:本次共处理 {total} 条") return total @task def once(ctx: Any, value: int) -> int: """一个短任务,用来对照"有始有终"的普通形态。""" del ctx return value * 2