djangoccelery で非同期処理をやる。
サクッと非同期処理を試せちゃうような、クイックスタートガイド をメモがてら書いていく。
インストール
まずはインストールから。
pip を使って Django と djangoccelery をインストールする。
% pip install Django % pip install django-celery
おわり。
バージョンは以下のようになった
% pip freeze Django==1.5 amqp==1.0.10 anyjson==0.3.3 billiard==2.7.3.23 celery==3.0.16 django-celery==3.0.11 kombu==2.5.8 python-dateutil==1.5 pytz==2013b wsgiref==0.1.2
設定
インストールできたら Django
のプロジェクト asynctest
と、 アプリケーション caculator
を作ってみる。
% django-admin.py startproject asynktest % cd asynktest % python manage.py startapp caculator
まずは設定ファイル (asynctest/asynctest/settings.py) に
djangoccelery
と先ほど作った caculator
、それとあと 裏方の kombu.transport.django
をいれてやる。
INSTALLED_APPS = ( ... 'djcelery', 'kombu.transport.django', 'caculator', )
こんなかんじに。
さらに、 djangoccelery に関する設定を追記する。
###### django-celery configuations ###### from djcelery import setup_loader setup_loader() BROKER_URL = 'django://' # Tasks will be executed asynchronously. CELERY_ALWAYS_EAGER = False
あとはDBと同期すればOK。
note
django-kombu
をインストールしなくても最近のkombu
と上記の設定で Django のDBをブローカーとして使えるよう。 djangoccelery インストールの段階でkombu
もインストール されてくれるので、とくにkombu
を意識する必要がなくなって しまった。
非同期処理させるもの
さて肝心の処理をおこなう関数を書く。 caculator/tasks.py を以下のように書いた。
import time from celery import task @task def add(a, b): time.sleep(10) return a + b
task
でデコレートしてあげるだけで良い。 add
関数は10秒スリープしてくれるという親切設計なので、
存分に非同期を味わうことができる。
あと、モジュール名は tasks.py にしましょうね。
実行してみる
準備ができたので非同期を味わってみる。 まずは Celery 氏を起動。
% python manage.py celeryd -l info
別のシェルから manage.py shell を起動。
% python manage.py shell
打っていく。
>>> from caculator.tasks import add >>> add(1, 2) # 10秒かかる 3 >>> add.run(1, 2) # 10秒かかる 3 >>> result = add.delay(1, 2) # 非同期で実行するには delay >>> result.ready() # ready で終了したかがわかる False >>> result.ready() # マダァ?(・∀・ )っ/凵⌒☆チンチン True >>> result.get() # 終わってたら get でとる 3 >>> # 処理終わってないのに get すると、 >>> # 値が返るまで待ってしまう >>> # タイムアウトしたい >>> >>> result = add.delay(3, 4) # もっかい計算 >>> result.get(timeout=3) # 3秒間だけ待つ Traceback (most recent call last): File "<console>", line 1, in <module> File "/path/to/celery/result.py", line 109, in get interval=interval) File "/path/to/celery/backends/base.py", line 186, in wait_for raise TimeoutError('The operation timed out.') TimeoutError: The operation timed out. >>> # 3秒以内に終わらなかったら TimeoutError >>> result.get(timeout=3) 7 >>> # 3秒以内なら結果が返る
こんなかんじで使えます。 やったね。非同期処理ができたよ。
重い処理があれば非同期でやらせて、ポーリングして結果待つとか サクッと書けてしまう。 Django 内で完結してできるから分かりやすくて楽。 djangoccelery 覚えていて損ないかと思う。
参考: