在 Celery 中,我如何运行一个任务,然后让该任务运行另一个任务并继续执行?

Posted

技术标签:

【中文标题】在 Celery 中,我如何运行一个任务,然后让该任务运行另一个任务并继续执行?【英文标题】:In Celery, how do I run a task, and then have that task run another task, and keep it going? 【发布时间】:2011-05-31 23:19:23 【问题描述】:
#tasks.py
from celery.task import Task
class Randomer(Task):
    def run(self, **kwargs):
        #run Randomer again!!!
        return random.randrange(0,1000000)


>>> from tasks import Randomer
>>> r = Randomer()
>>> r.delay()

现在,我运行简单的任务。它返回一个随机数。但是,我如何让它运行另一个任务,在该任务中

【问题讨论】:

您为什么要这样做?您是否正在尝试实现诸如 crontab 或看门狗之类的东西?如果是这样,这个问题是XY problem 的一个实例,询问您尝试解决的原始问题而不是询问如何实施您设计的解决方案会更有成效。 【参考方案1】:

您可以从Randomer.run 内部调用other_task.delay();在这种情况下,您可能需要设置Randomer.ignore_result = True(和other_task.ignore_result,等等)。

请记住,celery 任务 delay 会立即返回,因此如果您不对嵌套调用(或递归调用)设置任何限制或等待时间,您可以很快崩溃。

您应该考虑使用无限循环来避免堆栈溢出,而不是递归或嵌套任务。

from celery.task import Task
class Randomer(Task):
    def run(self, **kwargs):
        while True:
           do_something(**kwargs)
           time.sleep(600)

【讨论】:

你能展示一个示例代码吗?我不太明白你的意思 但我希望 do_something 是“Randomer()”。我可以在其中添加一个延迟,这样它就不会一直不停地走来走去。你是说我必须编写另一个名为“do_something”的函数,它与 randomer 类相同? “do_something”是指 Randomers 真正的工作。如果你想要一些事情继续下去,你需要一个循环,而不是一个队列;也许我错了,从您发布的示例中很难分辨。在任务中进行无限递归调用是危险的,您可以很快消耗所有计算机资源(崩溃)。【参考方案2】:

您可以按照此处所述链接子任务:http://docs.celeryproject.org/en/latest/userguide/canvas.html#chains

【讨论】:

链类似于,当您执行第一个任务并希望将其结果提供给第二个任务时,您应该链接这些任务。但这里的问题是不同的。链接就像管道一个任务结果到另一个。我认为提问者的意图是解决嵌套任务调用。 我猜 OP 想要实现类似 crontab 或 watchdog 之类的东西,而任务队列并不是最好的基础。

以上是关于在 Celery 中,我如何运行一个任务,然后让该任务运行另一个任务并继续执行?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 django celery 中处理未完成的任务

创建 celery 任务然后同步运行

如何在 Django 中运行和查看 celery 任务?

如何在 django 中删除 celery beat 任务

如何按名称限制运行 Celery 任务的最大数量

停止 Redis 后如何继续执行 celery 队列,然后再启动它?