web-dev-qa-db-ja.com

セロリの例外処理

私がこのタスク定義を持っているとしましょう:

def some_other_foo(input)
raise Exception('This is not handled!')
return input

@app.task(
  bind=True,
  max_retries=5,
  soft_time_limit=20)
def some_foo(self, someInput={}):
   response=""
   try:
     response = some_other_foo(someInput)
   except Exception as exc:
     self.retry(countdown=5, exc=exc)
     response="error"
 return response

Some_fooで例外が処理されないという問題があり、response = "error"ではなくエラーが発生し、タスクがクラッシュし、例外が発生したことを示すトレースバックが発生します。

通常の応答を返すことはできますが、セロリタスクを失敗として設定すると、結果として花が失敗しますか?

私は使っている:
セロリ4.1
ブローカーとしてのAMPQ
モニタリングとしてのセロリの花

6
xDan

_Try \ except_は正常に機能します。 returnの前に_self.retry_を呼び出したため、タスクは常に失敗します。少しテストしてみましょう:

_from celery import Celery

app = Celery(name_app,broker_settings_etc....)

def some_other_foo(value):
    raise Exception('This is not handled!')

@app.task(
  bind=True,
  max_retries=5,
  soft_time_limit=20)
def some_foo(self):
    response = ""

    try:
        response = some_other_foo('test')
    except Exception as exc:
        self.retry(countdown=5, exc=exc)
        response = "error"

    return response
_

セロリアプリを実行し、タスクを呼び出します。セロリログに次のようなものが表示されます。

_3fb-81de-e4149fa88f4c] retry: Retry in 5s: Exception('This is not handled!',)
[2017-08-18 15:50:34,160: INFO/MainProcess] Received task: tasks.some_foo[b656731b-c85d-43fb-81de-e4149fa88f4c] eta:[2017-08-18 12:50:39.156912+00:00]
[2017-08-18 15:50:34,161: INFO/MainProcess] Task tasks.some_foo[b656731b-c85d-43fb-81de-e4149fa88f4c] retry: Retry in 5s: Exception('This is not handled!',)
[2017-08-18 15:50:39,511: ERROR/MainProcess] Task tasks.some_foo[b656731b-c85d-43fb-81de-e4149fa88f4c] raised unexpected: Exception('This is not handled!',)
Traceback (most recent call last): 
# trace here...
Exception: This is not handled!
_

使い方。タスク_max_retries=5_を設定しました。 self.retry(countdown=5, exc=exc)を呼び出すと、Celeryはタスクの処理を中断し、countdown(この場合は5)でタスクを再開しようとします。 5回試行した後(_max_retries_)Celeryはタスクを再実行しません。

それでは、_try \ except_ブロックを次のように変更しましょう。

_try:
    response = some_other_foo('test')
except Exception:
    print 'handled'
    response = "bad response"
_

Celeryを再起動して、タスクを実行します。ログを確認しましょう:

_[2017-08-18 15:58:41,893: INFO/MainProcess] Received task: tasks.some_foo[1437e7ce-1c69-4042-824b-5602f486c025]
[2017-08-18 15:58:41,895: WARNING/Worker-3] handled
[2017-08-18 15:58:41,896: INFO/MainProcess] Task tasks.some_foo[1437e7ce-1c69-4042-824b-5602f486c025] succeeded in 0.00186271299026s: 'bad response'
_

ご覧のとおり、ハンドラーは正常に機能します。

だから、要約します。 _self.retry_を呼び出すと、Celeryはタスクの処理を中断し、現在のタスクを再開しようとします。

6
Danila Ganchar