4

我正在使用芹菜 3.0.12。

我有两个队列:Q1,Q2。

一般来说,我将主要任务放在 Q1 中,然后调用 Q2 中的子任务。我不想为子任务存储任何结果。所以我的子任务有装饰器@celery.task(ignore_results=True)。

我的主要任务现在应该等到子任务完成。因为我没有写结果。我不能使用:AsyncResult。有没有办法在主任务中等待子任务完成而不将状态存储到后端。我对 AsyncResults 的所有尝试都不是成功的燃料(它依赖于后端)。似乎 get() 也依赖于后端。

代码中的整个故事:

@celery.task(ignore_result=True)
def subtask():
   #Do something

@celery.task
def maintask():
    # Do something

    # Call subtask on Q2:
    res = subtask(options={'queue':'Q2'}).delay()

    # Need to wait till subtask finishes
    # NOT WORKING (DOES NEVER RETURN)
    res.get()

我正在用 Celery Flower 监控整个应用程序,我可以看到子任务正在成功完成。Celery 如何检测到这种状态?我浏览了他们的代码,但不知道他们是如何进行检测的。

4

1 回答 1

3

我的主要任务现在应该等到子任务完成。

您永远不应该等待子任务,因为这可能会导致资源匮乏和死锁(所有任务都在等待另一个任务,但没有更多的工作人员来处理它们)。

相反,您应该在子任务完成后使用回调来执行其他操作(请参阅 Celery 用户指南中的 Canvas 指南)。

我正在用 Celery Flower 监控整个应用程序,我可以看到子任务正在成功完成。Celery 如何检测到这种状态?我浏览了他们的代码,但不知道他们是如何进行检测的。

Flower 和其他监视器不使用结果(任务状态),而是使用我们所说的事件

当工作人员中发生某些操作时,会发出事件消息,这会成为消息的瞬态流。进程可以订阅某些事件(或所有事件)来监控集群。

事件与任务状态是分开的,因为,

  • 事件不是持久的(瞬态的)

    错过一个事件不被视为严重失败。

  • 复杂字段未序列化

    事件用于诊断和信息目的,不应用于自省任务返回值或异常,例如,因为仅repr()存储这些以确保可以用其他语言编写监视器,并且可能会截断大字段以确保更快传送。

于 2013-01-11T12:49:02.203 回答