Files

49 lines
1.7 KiB
Python
Raw Permalink Normal View History

"""一个可以直接用的常驻任务模块(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