読者です 読者をやめる 読者になる 読者になる

Just In Time Scheduler

Django

さっきPyPIにあがったばかりだけれども、ふと目に留まったので。

jits
http://pypi.python.org/pypi/jits/

jitsはDjangoのモデル・ミドルウェアを利用したジョブスケジューラー。TheSchwartzやActiveMQ、Quartzと違って、イベントループの中でジョブの実行を調整するのではなく、新しいHTTPリクエストを受けたタイミングでジョブの実行を調整する。

このHTTPリクエストを契機にしてジョブを実行というところがjitsの特徴だが、スレッドを使ってジョブを並列実行するので、一応HTTPリクエストの処理と非同期に、並列してジョブを実行できる。

あまり正しく動いている感じがしない、はっきり書くと、このモジュールは動かない*1のであるが、次のように使うように設計されている。まず、settings.pyにミドルウェア、アプリケーションとしてjitsを追加する。

MIDDLEWARE_CLASSES = (
    'django.middleware.common.CommonMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    # 下の行を追加
    'jits.middleware.JitsMiddleware',
    'django.middleware.doc.XViewMiddleware',
)

INSTALLED_APPS = (
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.sites',
    # 下の行を追加
    'jits.app',
)

ジョブの生産者側は、jits.add_task関数を使ってジョブを追加する。このとき引数callbackに呼び出し可能型を渡す。

from django.shortcuts import *
import jits

class HelloTaskCallback(object):
    def __init__(self, msg):
        self.msg = msg
    def __call__(self):
        """
        ここで何かする
        """
        import sys
        sys.stderr.write("%s\n" % msg)

def some_view(request):
    jits.add_task(callback=HelloTaskCallback('hello world'))
    return render_to_response('some.html')

あとは、上にも書いたとおりHTTPリクエストがくるたびに、ジョブの最終実行時間をチェックして必要であればジョブを呼び出してくれる・・・はず。
add_taskに追加の引数で、days, minutes等を指定すれば呼び出し間隔の調整も行える。


threadpoolモジュールの使い方や、Djangoのモデルで独自のフィールドを定義するやり方とかは参考になるが、この用途では普通にcronを使いそうな気がする。個人的には、TheSchwartzで満足しているっていうのもある。

*1:このエントリを書いている間に0.1.0から0.1.1にあがったので、もしかしたら明らかな間違いは直っているかもしれない