Django runserverのautoreload機能の概要
2667 ワード
Django runserverのautoreload機能の概要
by z9g
djangoプロジェクトでpython manangeを使用します.py runserver内蔵serverを起動すると、このプロジェクトのpythonファイルを変更すると、内蔵serverが自動的に再起動して新しいファイルをロードします.この機能はcoolに見え、開発デバッグ中に手動でserverを再起動する時間を大幅に節約します.今日は暇を見つけて実装されたコードを見てみると、このautoreloadの機能はdjangoとは完全に独立したモジュールであることが分かった.runserverはdjango Managementのcommandであり、ソースファイルの位置はdjangoディレクトリ/core/management/commands/runserverである.py、ファイルの最後にこのようなコードがいくつか表示されます.
if
use_reloader:
from
django.utils
import
autoreload
autoreload.main(inner_run)
else
:
inner_run()
本当に働いているのはinnerですrun、serverの自動再起動を担当するのはdjangoです.中のautoreloadreloadの判定条件は全てチェックsys.modulesの各モジュールファイルの最終変更時間は変化するかどうかは異なるが、pythonとjythonのスレッドメカニズムの違いによりautoreload.pyはpythonとjythonに対して異なる処理を行い、jython reloadeの実現:
def
jython_reloader(main_func, args, kwargs):
from
_systemrestart
import
SystemRestart
thread.start_new_thread(main_func, args)
while
True
:
if
code_changed():
raise
SystemRestart
time.sleep(
1
)
python環境での実装を比較するには、python_reloader環境変数RUN_を設定MAIN、それから1つの現在のプロセスのサブプロセス(スレッドではありませんよ)をコピーして、それからこの新しいプロセスの中で1つのスレッドを起動して本当に仕事をして、1つのスレッドはファイルが修正するかどうかを検査して、ファイルが修正する時、新しい起動のプロセス(sys.exit(3))を脱退して、この時親プロセスはファイルが修正したためかどうかを判断します(コードを返すのは3です)、はい、新しいプロセスを再起動して仕事をします.そうしないと、プログラム全体が終了します.具体的な詳細はやはりコードがもっとはっきりしているのを見て、autoreload全体のコードはdjangoと結合していないので、単独で使用することができます.次のような試みが行われました.
from
django.utils
import
autoreload
def
tt():
print
'aaa...'
while
True
:
pass
autoreload.main(tt)
保存し、コマンドラインで実行している間にソースコードを変更し、print'aaa...'をprint'bbb...'に変更します.保存すると、前に実行したプログラムの出力が次のように表示されます.
$ python tt.py
aaa...
bbb...
daemonプログラムをデバッグするときにautoreloadで自動ロード機能を追加するのはどんなにeasyなのかがわかります.
補足:その後、以下のwebpyのserver内蔵reload機能の実現、webpyでのアプリケーションを見ました.pyでreloadが見つかる時間は、requestごとにreloadの有無をチェックし、結合度がきついのが大まかな原理です.