Python 找出芹菜任务是否存在
是否可以确定是否存在具有特定任务id的任务?当我尝试获取状态时,我将始终处于挂起状态Python 找出芹菜任务是否存在,python,task,status,celery,Python,Task,Status,Celery,是否可以确定是否存在具有特定任务id的任务?当我尝试获取状态时,我将始终处于挂起状态 >>> AsyncResult('...').status 'PENDING' 我想知道给定的任务id是否是真正的芹菜任务id,而不是随机字符串。我想要不同的结果,这取决于是否存在针对特定id的有效任务 过去可能有一个具有相同id的有效任务,但结果可能已从后端删除。请重试 AsyncResult('blubb').state 这可能行得通 它应该返回不同的结果。您需要对所创建的AsyncT
>>> AsyncResult('...').status
'PENDING'
我想知道给定的任务id是否是真正的芹菜任务id,而不是随机字符串。我想要不同的结果,这取决于是否存在针对特定id的有效任务
过去可能有一个具有相同id的有效任务,但结果可能已从后端删除。请重试
AsyncResult('blubb').state
这可能行得通
它应该返回不同的结果。您需要对所创建的AsyncTask对象调用
.get()
,以实际从后端获取结果
看
进一步澄清我的回答 从技术上讲,任何字符串都是有效的ID,无法验证任务ID。确定任务是否存在的唯一方法是询问后端是否知道该任务,并且必须使用
.get()
这就引入了一个问题,.get()
在后端没有关于您提供的任务ID的任何信息时会阻塞,这在设计上允许您启动任务,然后等待任务完成
在最初的问题中,我假设OP想要获得之前完成的任务的状态。为此,您可以传递一个非常小的超时并捕获超时错误:
from celery.exceptions import TimeoutError
try:
# fetch the result from the backend
# your backend must be fast enough to return
# results within 100ms (0.1 seconds)
result = AsyncResult('blubb').get(timeout=0.1)
except TimeoutError:
result = None
if result:
print "Result exists; state=%s" % (result.state,)
else:
print "Result does not exist"
不用说,这只有在后端存储结果时才起作用,如果没有,则无法知道任务ID是否有效,因为没有任何东西保存它们的记录
甚至更多的澄清 您想要做的事情无法使用AMQP后端完成,因为
我的建议是切换到数据库后端,以便将结果保存在一个数据库中,您可以在现有芹菜模块之外查询该数据库。如果结果数据库中不存在任务,您可以假定ID无效。如果我错了,请更正我
if built_in_status_check(task_id) == 'pending'
if registry_exists(task_id) == true
print 'Pending'
else
print 'Task does not exist'
AsyncResult.state在任务ID未知的情况下返回挂起 未决 任务正在等待执行或未知。任何未指定的任务id “已知”表示处于挂起状态 如果需要区分未知ID和现有ID,可以提供自定义任务ID:
>>> from tasks import add
>>> from celery.utils import uuid
>>> r = add.apply_async(args=[1, 2], task_id="celery-task-id-"+uuid())
>>> id = r.task_id
>>> id
'celery-task-id-b774c3f9-5280-4ebe-a770-14a6977090cd'
>>> if not "blubb".startswith("celery-task-id-"): print "Unknown task id"
...
Unknown task id
>>> if not id.startswith("celery-task-id-"): print "Unknown task id"
...
现在我正在使用以下方案:
芹菜在发送任务时不会写入状态,这在一定程度上是一种优化 (见附件) 如果您确实需要它,可以简单地添加:
from celery import current_app
# `after_task_publish` is available in celery 3.1+
# for older versions use the deprecated `task_sent` signal
from celery.signals import after_task_publish
# when using celery versions older than 4.0, use body instead of headers
@after_task_publish.connect
def update_sent_state(sender=None, headers=None, **kwargs):
# the task may not exist if sent using `send_task` which
# sends tasks by name, so fall back to the default result backend
# if that is the case.
task = current_app.tasks.get(sender)
backend = task.backend if task else current_app.backend
backend.store_result(headers['id'], None, "SENT")
然后,您可以测试挂起状态,以检测任务是否(看起来)没有挂起
已发送:
>>> result.state != "PENDING"
我希望根据任务id是否是或曾经是真实的任务id获得不同的结果。问题是,即使我使用像blubb这样的假id,我也将始终处于挂起状态。
。status
是属性state
的不推荐别名。get()
将阻止,直到系统收到结果。如果ID不存在,这将锁定应用程序。您可以传递timeout
参数,但仍然无法确定任务id是否正确,您需要传递超时值并捕获超时错误。这是根据后端确定任务id是否“有效”的唯一方法。任何id在技术上都是“有效的”,但只有后端知道的id才会返回任何数据。我的任务通常持续30秒左右。所以这是没有选择的,对吗?您希望在任务完成之前获取有关任务的信息,但是要从创建任务的进程之外的另一个进程获取信息。基本上是为了检查是否有东西在运行?这是正确的吗?这是一个有用的答案,因为它澄清了如果没有超时
参数,.get()
有时将永远不会返回。关于在芹菜外存储任务状态的其他答案更为正确,因为代理不会永远存储数据。但是,切换到数据库作为代理并不是一个好主意(这样的后端仅用于测试,不支持一些芹菜功能)。什么是内置的\u状态\u检查
和注册表存在
?您将如何实现这一点?我知道有6种任务状态(挂起、启动、成功、失败、重试和吊销)。所以,我想我们可以有一个代码来检查任务是否处于“挂起”状态。如果它处于“挂起”状态,我们可以用注册表项检查该特定任务是否存在。不,我知道该状态处于挂起状态,但我不知道挂起的原因。我正在寻找一个智能注册表。\u存在
。问题是我只有一个id。每个id都曾经是一个有效id,但有些id不再有效,因为结果已从后端删除。因此,我的id总是以西芹任务id-开头,但任务可能仍然无效。在这种情况下,您应该从外部跟踪id历史记录。芹菜后端不能保证永远保存所有结果。例如,amqp后端只能查询一次。@0x00mh:问题是,如果有任务id,我如何判断任务是否真的挂起或已从后端删除(可能是因为我设置芹菜,以便在一段时间后忘记它)?这是我想要的方式,但似乎不是干净的方式。值得一提的是,清除队列不会删除任务元(至少在使用Redis作为后端时)。因此,无法可靠地使用此方法确定任务是否仍然存在。是否只需将此代码段添加到现有任务中?我把它们放在“tasks.py”模块中。此外,“result.state”只适用于