我对芹菜比较新。我要求我的芹菜任务之一应该在所有其他任务完成后启动。我确实玩过它并且还在网上发现了一些文档,其中表明我应该使用groups
和chords
等我完全无法理解的内容。
我还发布了另一个SO here的问题,但到目前为止还没有找到任何令人信服的答案。
最后我遇到了this SO question,我可以清楚地(至少从概念上)理解接受的答案中发生了什么。但是,当我尝试复制完全相同的程序时,它抛出了以下错误:
EncodeError: <AsyncResult: cf5875f1-7f72-449c-9808-07c9c9459737> is not JSON serializable
我在上述问题的评论中也发布了同样的问题,这个问题似乎很老,因此到目前为止我的评论还没有得到任何关注。
有人可以帮忙吗?
答案 0 :(得分:0)
如果
您已经有一个必须一个接一个地执行的任务列表,并希望合并您只能使用chords的结果。
else
如果您继续向celery添加任务(而不是立即执行),并且您希望逐个执行它们,那么只需设置1个并发= 1的工作程序即可实现此目的,任务只能通过串行执行。
我也遇到了并行执行问题,我通过在开始时运行一个并发= 1的worker来解决它,但后来我使用redis锁定机制来实现解决方法。
答案 1 :(得分:0)
this SO answer中接受的答案实际上帮助我实现了我想要的目标。 (这可能是一种hacky方式,但它解决了我的问题)。然而答案却产生了错误:
EncodeError: <AsyncResult: cf5875f1-7f72-449c-9808-07c9c9459737> is not JSON serializable
我能够解决如下(我在答案的评论中也提到了这一变化)
所以在答案中的用例部分:
tasks = []
for i in xrange(10):
tasks.append(power.delay(i, 2))
amass.delay([], tasks)
作为amass.delay()
的第二个参数,我们传递一个任务对象列表。我只是将其更改为实际传递任务ID列表。所以amass()
现在看起来像:
tasks = []
for i in xrange(10):
x = power.delay(i, 2)
tasks.append(x.id)
amass.delay([], tasks)
并在amass()
中进行了相应的更改,如下所示
它解决了错误并完成了我想要实现的工作。
@celery.task()
def amass(results, tasks):
completed_tasks = []
for task_id in tasks:
result = AsyncResult(task_id, app=celery)
if result.ready():
completed_tasks.append(task_id)
#results.append(task.get()) did not need this so commented it out
# remove completed tasks
tasks = list(set(tasks) - set(completed_tasks))
if len(tasks) > 0:
# resend the task to execute at least 1 second from now
amass.delay(results, tasks, countdown=1)
else:
# we done
print results