即使主要任务失败,是否可以运行chord回调?
我创建了一个和弦,我添加了一堆任务并注册了一个回调。我的问题是,如果其中一个任务失败,则不会触发回调,但我希望以任何一种方式触发回调。
我试图用si()(immutability)注册回调
callback = tasks.run_delete_rule.si([timestamp])
header = [tasks.run_update_rule.s(i, timestamp) for i in item_ids]
result = chord(header)(callback)
我还尝试将param ignore_result=True
添加到任务装饰器中,但没有成功。
答案 0 :(得分:8)
从github问题#1881如果回调设置了link_error
选项,其中列出了任务名称,那么当和弦的任务失败时,将执行link_error任务。
@task(name='super_task.good')
def good():
return True
@task(name='super_task.raise_exception')
def raise_exception():
raise ValueError('error')
@task(name='super_task.callback')
def callback(*args, **kwargs):
logger.info('callback')
logger.info(args)
logger.info(kwargs)
return 'finished'
@task(name='super_task.error_callback')
def error_callback(*args, **kwargs):
logger.info('error_callback')
logger.info(args)
logger.info(kwargs)
return 'error'
>>> c = chord(
[raise_exception.s(), good.s(), raise_exception.s()],
callback.s().set(link_error=['super_task.error_callback'])
)
>>> result = c()
这将执行和弦,在您的芹菜日志中,您将看到raise_exception
任务失败,并且error_callback
的执行会在其中收到任务#task_id callback
。
此时result
的值将包含AsyncResult
callback
的{{1}}实例,因为在和弦中,错误传播到回调result.get()
会引发任务例外,result.traceback
为您提供追溯。
如果您想要一个回调,只需将和弦回调的名称传递给link_error
callback.s().set(link_error='super_task.callback')
注意
设置CELERY_CHORD_PROPAGATES = False
的另一个选项是恢复到芹菜前的行为并始终执行回调。
但这不是推荐的方法,因为你可以在github问题中找到#1349
Celery 3.1定义了如何处理和弦错误,以前的行为从未记录过 而且更多的是因为从来没有打算以这种方式工作。
我们无法更改错误修正版本中的行为,因此必须使用设置, 但从来没有人故意禁用新行为。
新行为可以防止发生此类问题,并且可以删除向后兼容设置。我建议你在这里找到一些其他方法来处理错误(如果你能为它创造一个好的API,我也不会介意提议)
答案 1 :(得分:0)
您只需要更改调用link_error
的方式即可。代替字符串引用,使用所需参数传递签名。
在上面的示例中,您可以按以下方式传递参数
c = chord(
[raise_exception.s(), good.s(), raise_exception.s()],
callback.s().set(link_error=[error_callback.s(<arguments_here>)])
)
请记住,第一个参数为task_id
,其他参数为签名中定义的参数。