daily dayflower

2012-10-17

uWSGI でファイルが更新された時にリロードする

最初は inotifyx 使って自力で書こうとしてたんだけど,ブロックしてうまくいかなかったりして,thread でも立てなきゃいけないのかなと思って uwsgidecorators を読んでたら,そもそも uwsgidecorators (というかそもそも uwsgi-core) にファイル更新検知機能がついてた。

メインとなる wsgi ファイルが main.wsgi というファイル名だったとして,監視するモジュール*1 watcher.py は:

# watcher.py
import uwsgi
from uwsgidecorators import filemon

@filemon('main.wsgi')
def reloaded(num):
    uwsgi.reload()

対応する uWSGI のパラメータは,たとえば:

; uwsgi.ini
[uwsgi]
master = true
plugins = python,http
http = :8000
wsgi-file = main.wsgi
import = watcher

ファイルがいっぱいあったらどうすんねーんと思うかもしれないけど,@filemon デコレータは,ディレクトリの監視もできます。

ちなみに内的には inotify 機構を使っているので無駄はないはず。IN_ALL_EVENTS レベルの監視をしてるんで,touch とかしてもちゃんとリロードされます。



あと今回の話と関係ないけど,たとえば 1 分間リクエストがなかった場合にワーカーを自動的に kill するには

idle = 60

のようにしておけばよい。uWSGI 使うようなシチュエーションでそんなにメモリをケチるシーンはないかもしんないけど。

追記: idle (や lazy) と @filemon の相性はよくないかもしんない。ワーカーがいない状態で編集してリクエスト投げたら編集前の内容だったことがあった。気のせいかもしれないけど。


もういっこわりと便利なオプションharakiri

harakiri = 60

のようにしておくと,処理に 60 秒以上かかるワーカーは強制的に落とされます。

*1:別モジュールだてにしなくてもいい (main.wsgi に入れ込む) のかもしれないけど追ってない追記: やってみたら別モジュールに独立させなくてもうまくいった。小さい捨て WSGI スクリプトであればリロードのロジックを入れ込むのが楽。(もちろん,WSGI アプリケーションとして独立させるなら入れ込まないほうがいいけど)

スパム対策のためのダミーです。もし見えても何も入力しないでください
ゲスト


画像認証

トラックバック - http://d.hatena.ne.jp/dayflower/20121017/1350447805
Connection: close