LoginSignup
3
2

More than 5 years have passed since last update.

celeryでタスクをインポートせずに呼ぶには

Posted at

背景

pythonアプリでメッセージキューイングを利用したい。そこでRabbitMQ+Celeryを選択したが、環境の都合によりcallerはPython2でworkerは3で動かしている。

環境

Linux Mint 17
Python:callerは2.7.6(Mint標準)、workerは3.5.2
RabbitMQ:3.2.4-1
celery:4.0.2

困ったこと

Celeryのチュートリアルには、タスクを呼ぶ為にはcaller側でもタスクを定義したモジュールをインポートしろとある。ところがインポートすると、callerとworkerのPythonのバージョンの違いにより、エラーになる。

tasks.py

from celery import Celery
celery.config_from_object('celeryconfig')

@celery.task
def add(x, y):
    return x + y

caller.py

from tasks import add #ここでエラーになる/そもそもファイルが見えない

add.delay(4, 4)

おかしいな

callerとworkerの間には当然brokerが介在し、amqpというプロトコルで通信する。今回は同一ホストだが、リモートでも分散環境でも対応しているはず。そういう環境ではインポート出来るとは限らんやんね?そもそも何故インポートしている?メソッドシグネチャの読み取り?

結論を早く言え

タスク名を文字列で渡せるメソッドがありました。引数はapply_asyncと同じだそうです。

caller.py(改)

from celery import Celery
celery.config_from_object('celeryconfig')

result =celery.send_task('add', (4, 4), queue = 'hayosei')
result.get(timeout = 1000)

注意点

メソッド名=タスク名であってもタスク名の定義は必須。workerにそんなタスクは知らんと言われたらチェック。

tasks.py(改)

from celery import Celery
celery.config_from_object('celeryconfig')

@celery.task(name='add')
def add(x, y):
    return x + y

参考サイト

python - Celery - How to send task from remote machine? - Stack Overflow
correct task definitions when using tasks by name.
公式の説明

3
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2