Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/290.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 找出芹菜任务是否存在_Python_Task_Status_Celery - Fatal编程技术网

Python 找出芹菜任务是否存在

Python 找出芹菜任务是否存在,python,task,status,celery,Python,Task,Status,Celery,是否可以确定是否存在具有特定任务id的任务?当我尝试获取状态时,我将始终处于挂起状态 >>> AsyncResult('...').status 'PENDING' 我想知道给定的任务id是否是真正的芹菜任务id,而不是随机字符串。我想要不同的结果,这取决于是否存在针对特定id的有效任务 过去可能有一个具有相同id的有效任务,但结果可能已从后端删除。请重试 AsyncResult('blubb').state 这可能行得通 它应该返回不同的结果。您需要对所创建的AsyncT

是否可以确定是否存在具有特定任务id的任务?当我尝试获取状态时,我将始终处于挂起状态

>>> 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"
... 

现在我正在使用以下方案:

  • 获取任务id
  • 设置为memcache键,如“task\uu%s”%task.id消息“Started”
  • 将任务id传递给客户端
  • 现在,我可以从客户端监视任务状态(从任务消息设置为memcache)
  • 从就绪时的任务-设置为memcache密钥消息“就绪”
  • 在任务准备就绪时从客户端启动特殊任务,该任务将从memcache中删除密钥并执行必要的清理操作

  • 芹菜在发送任务时不会写入状态,这在一定程度上是一种优化 (见附件)

    如果您确实需要它,可以简单地添加:

    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”只适用于