这篇文章主要是在记录,celery 的任务状态以及该如何删除在任务伫列中的任务
有问题欢迎留言讨论喔!!
一、Celery 中的任务状态
Celery 内部对于任务的状态有 PENDING、STARTED、SUCCESS、FAILURE、RETRY、REVOKED,然而,笔者这边不推荐直接读取 Celery Backend 的状态,因为不见得符合每个任务的需求,最好的方式是针对每个任务,撰写一套任务的模组、状态以及相对应的 CRUD,会更加体现不同任务的状态,下面简单针对各个状态做一些定义
PENDING -> 任务正在等待执行或未知,任何未知的任务 ID 都默认处于 PENDINGSTARTED -> 任务已经开始,在 Celery Backend 中,默认不会记录,需要另外启用SUCCESS -> 任务执行成功FAILURE -> 任务执行失败RETRY -> 任务处于重试状态REVOKED -> 任务取消二、取消任务
我们可以利用 celery 提供的控制模组来对任务进行控制,举凡观察、停止等,下面简单介绍该如何将任务进行取消
建立任务 (task.py)import datetimefrom celery import Celeryfrom setting import broker_url, backend_urlapp = Celery("celery_start", broker=broker_url, backend=backend_url)@app.taskdef get_time(name: str): return f"Hello {name}, today is {datetime.datetime.now().isoformat()}"
利用程式送出任务说明: Celery 在送出任务后,会回传一个任务的类别,里面包含了 Celery 会存在本身 Backend 的一些资讯,例如 id、result、states...... 等等,而取消任务会需要用到 id
from task import get_time, app# 送出任务test_task = get_time.apply_async(("nick",), countdown=60)
import Control 模组,实作并利用 revoke 方法import timefrom task import get_time, appfrom celery.app.control import Control# 送出任务test_task = get_time.apply_async(("nick",), countdown=60)time.sleep(5)control_obj = Control(app) # 记得要将 celery 物件带入control_obj.revoke(task_id=test_task.id)
可以看到 celery 在收到 revoke 指令后,会先将任务标记为 revoke,在 countdown or eta 到期后,才会正式将该任务删除
若想直接删除任务可以加上 terminate=True
参数,这个指令也可以强制关闭正在执行的任务,然而这个指令似乎只会在 linux 系统上产生作用,于 windows 上并没有任何作用,若不幸的任务已经开始执行,只能等待任务执行完毕或手动强制关闭,才会停止
control_obj.revoke(task_id=test_task.id, terminate=True)