首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >从超出max_retries的任务恢复失败

从超出max_retries的任务恢复失败
EN

Stack Overflow用户
提问于 2011-06-28 07:04:51
回答 3查看 13.7K关注 0票数 22

我正在尝试异步使用web服务,因为它需要45秒才能返回。不幸的是,这个web服务也有点不可靠,可能会抛出错误。我已经设置了django-celery并执行了我的任务,它工作得很好,直到任务在max_retries之外失败。

这是我到目前为止所知道的:

代码语言:javascript
复制
@task(default_retry_delay=5, max_retries=10)
def request(xml):
    try:
        server = Client('https://www.whatever.net/RealTimeService.asmx?wsdl')
        xml = server.service.RunRealTimeXML(
            username=settings.WS_USERNAME,
            password=settings.WS_PASSWORD,
            xml=xml
        )
    except Exception, e:
        result = Result(celery_id=request.request.id, details=e.reason, status="i")
        result.save()
        try:
            return request.retry(exc=e)
        except MaxRetriesExceededError, e:
            result = Result(celery_id=request.request.id, details="Max Retries Exceeded", status="f")
            result.save()
            raise
    result = Result(celery_id=request.request.id, details=xml, status="s")
    result.save()
    return result

不幸的是,retry()没有抛出MaxRetriesExceededError,所以我不确定如何处理这个任务的失败。Django已经将HTML返回给了客户端,我正在通过AJAX检查Result的内容,它永远不会进入full fail f状态。

因此,问题是:当Celery任务超过max_retries时,我如何更新数据库

EN

回答 3

Stack Overflow用户

发布于 2016-02-27 10:39:53

问题是,当芹菜达到重试限制时,它会尝试重新引发您传入的异常。执行此重新提升的代码如下:https://github.com/celery/celery/blob/v3.1.20/celery/app/task.py#L673-L681

解决这个问题最简单的方法就是根本不让celery来管理你的异常:

代码语言:javascript
复制
@task(max_retries=10)
def mytask():
    try:
        do_the_thing()
    except Exception as e:
        try:
            mytask.retry()
        except MaxRetriesExceededError:
            do_something_to_handle_the_error()
            logger.exception(e)
票数 18
EN

Stack Overflow用户

发布于 2012-02-20 21:21:11

在Celery版本2.3.2中,这种方法对我来说效果很好:

代码语言:javascript
复制
class MyTask(celery.task.Task):
    abstract = True

    def after_return(self, status, retval, task_id, args, kwargs, einfo):
        if self.max_retries == self.request.retries:
            #If max retries is equal to task retries do something

@task(base=MyTask, default_retry_delay=5, max_retries=10)
def request(xml):
    #Your stuff here
票数 15
EN

Stack Overflow用户

发布于 2014-05-23 08:37:16

我只是暂时这样做,省去了对Task进行子类化的工作,而且很容易理解。

代码语言:javascript
复制
# auto-retry with delay as defined below. After that, hook is disabled.
@celery.shared_task(bind=True, max_retries=5, default_retry_delay=300)
def post_data(self, hook_object_id, url, event, payload):
    headers = {'Content-type': 'application/json'}
    try:
        r = requests.post(url, data=payload, headers=headers)
        r.raise_for_status()
    except requests.exceptions.RequestException as e:
        if self.request.retries >= self.max_retries:
            log.warning("Auto-deactivating webhook %s for event %s", hook_object_id, event)
            Webhook.objects.filter(object_id=hook_object_id).update(active=False)
            return False
        raise self.retry(exc=e)
    return True
票数 11
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6499952

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档