如何处理芹菜的Task.map中的错误

时间:2015-10-13 15:33:38

标签: python dictionary exception-handling celery

说我有两个芹菜任务:

@celery.task
def run_flakey_things(*args, **kwargs):
    return run_flakey_and_synchronous_thing.map(
        xrange(10)
    ).apply_async()


@celery.task
def run_flakey_and_synchronous_thing(a):
    if a % 5:
        return a
    raise RuntimeError(a)

因此,当你去运行run_flakey_things时,它会立即摔倒,因为序列中的第一项会引发异常。我想要的是按顺序顺序运行所有项目的任务,但继续在异常上运行,一旦所有这些项目完成就引发新的异常。

理想情况是,如果我可以在应用之前向xmap对象添加on_failure,但xmap似乎不是一个完整的任务对象。

2 个答案:

答案 0 :(得分:0)

我没有用过芹菜。但是,您可以在子任务中添加__call__方法吗?类似的东西:

class MyTask:
    def __call__(self, *args, **kwargs): 
        try: 
            super(self, MyTask).__call__(*args, **kwargs) 
        except Exception, exc:
            # store exc to be raised later in the main task

@celery.task(base=MyTask):
def run_flakey_and_synchronous_thing(a):
    # ...

然后对于主run_flakey_things任务,可以覆盖apply_async()以检索存储的异常,如How to override __call__ in celery on main?中所示。

答案 1 :(得分:0)

您可以更改返回值以指示并传播错误。像这样:

import traceback

@celery.task
def run_flakey_things(*args, **kwargs):
    return run_flakey_and_synchronous_thing.map(
        xrange(10)
    ).apply_async()


@celery.task
def run_flakey_and_synchronous_thing(a):
    d = {'value': None, 'error': None}
    try:
        if a % 5:
            d['value'] = a
    except:
        d['error'] = traceback.format_exc()
    return d

然后你可以做一些事情:

1)将run_flakey_things更改为包含和不包含错误的内容,返回没有错误的内容并报告错误内容。

2)处理调用run_flakey_things

的任何行为