初始提交:chongming-task 任务控制库
单任务受控执行(15 态状态机 + 审计轨迹)、DAG 管道、Controller 门面。
执行器三个:线程(默认,含 async def 任务)、内联(同步 / 测试)、进程
(spawn 子进程:硬性停止、绕开 GIL、崩溃隔离)。
调度:并发额度 + 每桶限流 + 具名资源信号量(按标签)+ 优先级排队。
持久层:TaskStore 契约 + 内存 / SQLite / Postgres 实现,契约测试随包发布。
跨进程与多节点:写穿 / 读穿、指令通道与租约、owned_buckets 划界、reconcile。
CLI、12 个可直接运行的示例、docs/ 下 5 份文档。
门禁:ruff / ruff format / mypy(strict) 干净;
pytest 563 passed(44 skipped 是需要真实 Postgres 的那批);
带一台可连的 Postgres 时 607 passed。
This commit is contained in:
@@ -0,0 +1,48 @@
|
||||
"""一个可以直接用的常驻任务模块(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
|
||||
Reference in New Issue
Block a user