概要
タイトルの通りです
visibility timeout に設定した秒数が経過した場合にタスクがどうなるかの影響を試してみました
環境
- macOS 11.7.2
- Python 3.10.2
- celery v5.2.7
サンプルコード
- vim celeryconfig.py
result_backend = "redis://localhost"
broker_url = "redis://localhost"
worker_prefetch_multiplier = 1
task_acks_late = True
result_backend_transport_options = broker_transport_options = { 'visibility_timeout': 5 }
- vim task.py
import time
from celery import Celery
app = Celery("tasks")
app.config_from_object("celeryconfig")
@app.task(bind=True)
def add(self, x, y):
return x + y
@app.task(bind=True)
def multi(self, x, y):
time.sleep(1800)
return x * y
起動
-
pipenv run celery -A tasks worker --loglevel=info
-
vim app.py
from celery import chain
from tasks import add, multi
tasks = chain(add.s(1, 2),
multi.s(10),
multi.s(2)).apply_async()
print(tasks.get())
起動
- pipenv run python app.py
動作確認
実行時のログは以下のようになりました
[2023-01-27 11:50:19,854: INFO/MainProcess] Connected to redis://localhost:6379//
[2023-01-27 11:50:19,862: INFO/MainProcess] mingle: searching for neighbors
[2023-01-27 11:50:20,875: INFO/MainProcess] mingle: all alone
[2023-01-27 11:50:20,894: INFO/MainProcess] celery@node1.local ready.
[2023-01-27 11:50:24,696: INFO/MainProcess] Task tasks.add[f4ca797b-1a76-4800-8a5f-ce7e39ad727d] received
[2023-01-27 11:50:24,718: INFO/MainProcess] Task tasks.multi[322d8025-e7ea-43d6-8f7f-e54008d46db4] received
[2023-01-27 11:50:24,719: INFO/ForkPoolWorker-2] Task tasks.add[f4ca797b-1a76-4800-8a5f-ce7e39ad727d] succeeded in 0.019410155015066266s: 3
[2023-01-27 11:51:49,898: INFO/MainProcess] Task tasks.multi[322d8025-e7ea-43d6-8f7f-e54008d46db4] received
[2023-01-27 11:53:29,947: INFO/MainProcess] Task tasks.multi[322d8025-e7ea-43d6-8f7f-e54008d46db4] received
ちょっと解説
どうやら visibiity_timeout に設定した時間が経過してすぐに再キューされるわけではないようです
何度か試してみましたがまちまちで visibility_timeout = 5 のときは 1 分から 2 分後に再キューされるような挙動でした
なので visibility_timeout = 5 だからと言って time.speep(10) くらいにしてしまうと再キューが発生することなく正常に終了してしまいます
また ack_late = True のオプション (もしくは task_acks_late = True) に設定していないと visibility_timeout の時間が反映されないようなのでそこも注意が必要です
最後に
プリフェッチを無効にする場合に task_acks_late = True
の設定が必須なのでその場合には visibiliti_timeout の設定も合わせて調整する必要がありそうです