【发布时间】:2014-10-03 06:48:20
【问题描述】:
使用 Celery 构建一系列顺序任务的最佳方法是什么?我的代码有一堆独立的任务(所以它们都可以是不可变的签名),但是如果其中一个任务抛出异常,我想停止序列。
我一直在寻找解决此问题的方法,但我被困住了。我们正在使用 Celery 3.1.12 + RabbitMQ。
一开始,我们使用一个和弦来表示头部任务成功,以便回调发生。它工作得很好,除了我们需要在标题中添加更多任务。
所以我试着在和弦上做一个链条。这也可行,但弦会因 PENDING 而挂起,因为当子任务引发异常时链不会退出。
一个人为的例子:
@celery.task
def bite(food):
if food == 'salad':
raise TypeError('Throwing up. I hate {}'.format(food))
print "bite {}...".format(food)
return True
@celery.task
def chew(food):
print "chewing {}...".format(food)
return True
@celery.task
def swallow(food):
print "swallowing {}...".format(food)
return True
@celery.task
def chain_in_chord(food):
return chord(
chain(
bite.si(food), chew.si(food)
),
swallow.si(food)
).delay()
如果 food=salad,bite 子任务会抛出异常。并且链的其余部分不会发生 - 这就是我想要的。但是整个和弦都卡在了 PENDING 状态,因为链卡在 PENDING 并且不会退出。
>>> res = foo.chain_in_chord('salad')
>>> res.status
'PENDING'
所以我需要:
- 找出一种方法来中止链并重新引发异常,如果 链失败
- 或者,找出一种方法来指定多个子任务 和弦的标题(我似乎做不到)。
在线搜索,chain 显然表现如预期 - 所以你必须遍历 asyncResult 的每个父状态。我更喜欢一种机制,让整个事情中止并重新引发异常/跟踪......就像和弦一样,但可以选择添加多个子任务。
任何反馈都将不胜感激。谢谢。
【问题讨论】:
标签: django task celery chain chord