23

返されるまでに最大 45 秒かかるため、Web サービスを非同期で使用しようとしています。残念ながら、この Web サービスも信頼性が低く、エラーをスローする可能性があります。django-celeryタスクが を超えて失敗するまで正常に動作するタスクをセットアップして実行していmax_retriesます。

これが私がこれまでに持っているものです:

@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

残念ながら、MaxRetriesExceededErrorは によってスローされretry()ていないため、このタスクの失敗を処理する方法がわかりません。ResultDjango は既に HTML をクライアントに返しています。AJAX 経由でコンテンツをチェックしていますが、完全な失敗f状態になることはありません。

問題は、Celery タスクが超過したときにデータベースを更新するにはどうすればよいかということmax_retriesです。

4

4 に答える 4

16

セロリタスククラスのafter_returnメソッドをオーバーライドできます。このメソッドは、タスクの実行後に、retステータス(SUCCESS、FAILED、RETRY)が何であれ呼び出されます。

class MyTask(celery.task.Task)

    def run(self, xml, **kwargs)
        #Your stuffs here

    def after_return(self, status, retval, task_id, args, kwargs, einfo=None):
        if self.max_retries == int(kwargs['task_retries']):
            #If max retries are equals to task retries do something
        if status == "FAILURE":
            #You can do also something if the tasks fail instead of check the retries

http://readthedocs.org/docs/celery/en/latest/reference/celery.task.base.html#celery.task.base.BaseTask.after_return

http://celery.readthedocs.org/en/latest/reference/celery.app.task.html?highlight=after_return#celery.app.task.Task.after_return

于 2011-06-28T07:23:10.107 に答える
15

Celery バージョン 2.3.2 では、このアプローチはうまく機能しました。

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
于 2012-02-20T13:21:11.327 に答える