如何在Celery中检查任务状态?

时间:2012-01-27 13:42:20

标签: python web-services celery django-celery

如何检查任务是否在芹菜中运行(具体来说,我使用的是celery-django)?

我已经阅读了文档,我用谷歌搜索了,但我看不到像这样的电话:

my_example_task.state() == RUNNING

我的用例是我有一个用于转码的外部(java)服务。当我发送要转码的文档时,我想检查运行该服务的任务是否正在运行,如果没有,则(重新)启动它。

我正在使用当前的稳定版本 - 2.4,我相信。

13 个答案:

答案 0 :(得分:79)

返回task_id(由.delay()提供),然后向celery实例询问状态:

x = method.delay(1,2)
print x.task_id

询问时,使用此task_id获取新的AsyncResult:

from celery.result import AsyncResult
res = AsyncResult("your-task-id")
res.ready()

答案 1 :(得分:54)

每个Task对象都有一个.request属性,其中包含AsyncRequest个对象。因此,以下行给出了任务task的状态:

task.AsyncResult(task.request.id).state

答案 2 :(得分:51)

从任务ID 创建AsyncResult对象FAQ中建议的方式,以便在您拥有的唯一内容是任务ID时获取任务状态。< / p>

然而,从Celery 3.x开始,如果他们不注意它们,就会有一些重要的警告。这实际上取决于具体的用例场景。

默认情况下,Celery不会记录“正在运行”状态。

为了让Celery记录任务正在运行,您必须将task_track_started设置为True。这是一个简单的任务,测试这个:

@app.task(bind=True)
def test(self):
    print self.AsyncResult(self.request.id).state

task_track_startedFalse时,默认情况下,状态显示为PENDING,即使任务已启动。如果您将task_track_started设置为True,则状态为STARTED

PENDING表示“我不知道。”

状态为AsyncResult的{​​{1}}并不意味着Celery不知道任务的状态。这可能是由于多种原因造成的。

首先,PENDING可以使用无效的任务ID构建。这些“任务”将被Celery视为未决:

AsyncResult

好的,所以没有人会将明显无效的ID提供给>>> task.AsyncResult("invalid").status 'PENDING' 。很公平,但它也有效, AsyncResult也会考虑一个已经成功运行但Celery忘记为AsyncResult的任务。再次, in一些用例场景这可能是个问题。部分问题取决于Celery如何配置以保持任务结果,因为它取决于结果后端中“墓碑”的可用性。 (“Tombstones”是Celery文档中用于记录任务结束方式的数据块的术语。)如果task_ignore_resultPENDING,则使用AsyncResult将无效。一个更令人烦恼的问题是Celery默认会使墓碑过期。默认情况下,result_expires设置为24小时。因此,如果您启动任务,并在长期存储中记录该ID,并在24小时后再创建True,则状态为AsyncResult

所有“真实任务”都从PENDING状态开始。因此,在任务上获得PENDING可能意味着该任务被请求但从未进一步发展(无论出于何种原因)。或者它可能意味着任务已经完成,但Celery忘记了它的状态。

哎哟! PENDING对我不起作用。我还能做什么?

我更愿意跟踪目标,而不是跟踪任务本身。我确实保留了一些任务信息,但它确实是继续跟踪目标。目标存储在独立于Celery的存储中。当请求需要执行计算取决于已经实现的某个目标时,它会检查目标是否已经实现,如果是,则使用此缓存目标,否则它将启动将影响目标的任务,并发送到使HTTP请求成为响应的客户端,指示它应该等待结果。

上面的变量名称和超链接适用于Celery 4.x.在3.x中,相应的变量和超链接是:CELERY_TRACK_STARTEDCELERY_IGNORE_RESULTCELERY_TASK_RESULT_EXPIRES

答案 3 :(得分:15)

您还可以创建自定义状态并更新其值静止任务执行。 此示例来自docs:

@app.task(bind=True)
def upload_files(self, filenames):
    for i, file in enumerate(filenames):
        if not self.request.called_directly:
            self.update_state(state='PROGRESS',
                meta={'current': i, 'total': len(filenames)})

http://celery.readthedocs.org/en/latest/userguide/tasks.html#custom-states

答案 4 :(得分:9)

老问题,但我最近遇到了这个问题。

如果您正在尝试获取task_id,可以这样做:

import celery
from celery_app import add
from celery import uuid

task_id = uuid()
result = add.apply_async((2, 2), task_id=task_id)

现在您确切知道task_id是什么,现在可以使用它来获取AsyncResult:

# grab the AsyncResult 
result = celery.result.AsyncResult(task_id)

# print the task id
print result.task_id
09dad9cf-c9fa-4aee-933f-ff54dae39bdf

# print the AsyncResult's status
print result.status
SUCCESS

# print the result returned 
print result.result
4

答案 5 :(得分:1)

只需使用celery FAQ中的此API

result = app.AsyncResult(task_id)

这很好。

答案 6 :(得分:1)

2020年的答案

#### tasks.py
@celery.task()
def mytask(arg1):
    print(arg1)

#### blueprint.py
@bp.route("/args/arg1=<arg1>")
def sleeper(arg1):
    process = mytask.apply_async(args=(arg1,)) #mytask.delay(arg1)
    state = process.state
    return f"Thanks for your patience, your job {process.task_id} \
             is being processed. Status {state}"

答案 7 :(得分:0)

尝试:

task.AsyncResult(task.request.id).state

这将提供Celery Task状态。如果Celery Task已经处于 FAILURE 状态,则会抛出异常:

raised unexpected: KeyError('exc_type',)

答案 8 :(得分:0)

对于简单任务,我们可以使用http://flower.readthedocs.io/en/latest/screenshots.htmlhttp://policystat.github.io/jobtastic/进行监控。

对于复杂的任务,说一个处理很多其他模块的任务。我们建议您在特定任务单元上手动记录进度和消息。

答案 9 :(得分:0)

我在

中找到了有用的信息

Celery Project Workers Guide inspecting-workers

就我而言,我正在检查Celery是否正在运行。

inspect_workers = task.app.control.inspect()
if inspect_workers.registered() is None:
    state = 'FAILURE'
else:
    state = str(task.state) 

您可以通过检查来满足您的需求。

答案 10 :(得分:0)

除了上述程序化方法 使用Flower Task状态很容易看到。

使用Celery Events进行实时监控。 Flower是一个基于Web的工具,用于监视和管理Celery集群。

  1. 任务进度和历史
  2. 能够显示任务详细信息(参数,开始时间,运行时等)
  3. 图表和统计数据
  4. 官方文件: Flower - Celery monitoring tool

    安装:

    $ pip install flower
    

    用法:

    http://localhost:5555
    

答案 11 :(得分:0)

  • 首先,在您的芹菜APP中:

vi my_celery_apps / app1.py

app = Celery(worker_name)
  • 然后,转到任务文件,从celery应用程序模块中导入应用程序。

vi task / task1.py

from my_celery_apps.app1 import app

app.AsyncResult(taskid)

try:
   if task.state.lower() != "success":
        return
except:
    """ do something """

答案 12 :(得分:-1)

<!-- https://mvnrepository.com/artifact/io.cucumber/cucumber-spring -->
<dependency>
    <groupId>io.cucumber</groupId>
    <artifactId>cucumber-spring</artifactId>
    <version>6.2.2</version>
</dependency>