我想并行启动多个子进程,然后将其结果传递给另一个任务。我认为这似乎是一个非常标准的方案,但是我无法使其正常工作。当我使用单个工人池时,一切似乎都正常,但是当我使用工人池时,一切都没有。
一个完全精简和人为设计的示例是在不同服务器上运行的2个python文件。
tasks.py
from celery import Celery
from functools import reduce
app = Celery('tasks', backend='redis://redis:6379/0', broker='redis://redis:6379/0')
app.conf.task_routes = {'tasks.*': {'queue': 'tasks'}}
@app.task
def mul(x, y):
print(f'{x} * {y} = { x * y }')
return x * y
if __name__ == '__main__':
app.start()
maths.py
from celery import Celery
app = Celery('maths', backend='redis://redis:6379/0', broker='redis://redis:6379/0')
app.conf.task_routes = {'maths.*': {'queue': 'maths'}}
@app.task
def add(a, b):
print(f'{a} + {b} = {a + b}')
return a + b
if __name__ == '__main__':
app.start()
我从
开始celery -A tasks worker -E -Q tasks
和
celery -A maths worker -E -Q maths
分别
然后,在我的本地主机上,运行以下命令:
from tasks import mul
from maths import add
from celery import group
print(mul.delay(2, 3).get())
print(add.delay(2, 3).get())
print(group(mul.s(2, 3), add.s(2, 3))().get())
前2条print
语句回显到终端,但第3条仅挂起,并且提示直到我发送SIGTERM
时才返回。查看这两个服务的日志,我看到了它们的打印语句的输出:
tasks_1 | [2019-02-04 21:03:58,181: WARNING/ForkPoolWorker-2] 2 * 3 = 6
maths_1 | [2019-02-04 21:03:58,188: WARNING/ForkPoolWorker-2] 2 + 3 = 5
tasks_1 | [2019-02-04 21:03:58,200: WARNING/ForkPoolWorker-2] 2 * 3 = 6
maths_1 | [2019-02-04 21:03:58,202: WARNING/ForkPoolWorker-2] 2 + 3 = 5
因此很明显,任务正在执行,但是,我认为结果永远不会把它返回给调用者。有没有一种方法可以配置芹菜来处理这种情况?虽然我只用group
展示了此问题,但chord
也具有相同的行为。