runserver がどう動いているか実装をみる
いつも開発で使うことになる runserver
。これはどういう風にしてうごいているのかを確認してみる。あと、 middleware がどう動くか実装をみる - そのあれ でかいた BaseHandler
がどこで挿入されているか確認する。
参考
おさらい
実行するコマンドはこういうやつ
python manage.py runserver python manage.py runserver 0.0.0.0:8000 python manage.py runserver 0.0.0.0:8001 --settings=proj.settings
実行コマンドをみる
読むモジュールは django 標準で登録されているので django.core.management.commands.runserver
BaseCommand.handle が起点になるのは manage.py(django-admin.py)でコマンドを実行するための実装を見る - そのあれ で確認したとおり。
流れ
- self.handle
- self.run
- self.inner_run
- self.validate
- self.check_migrations
- self.get_handler
- get_internal_application
- run
BaseHandler がつかわれているところ
get_internal_application
ではこういう実装になっている(ちょっと端折っている)。
app_path = getattr(settings, 'WSGI_APPLICATION') if app_path is None: return get_wsgi_application() try: return import_string(app_path)
docstring にかいてあるのだけど、 settings に WSGI_APPLICATION
を指定していなければ get_wsgi_application
が呼ばれるので、前回書いた内容通りの WSGIHandler
が使われる。settings の WSGI_APPLICATION
でのデフォルトは proj.wsgi.application
という風に生成されている。実際 wsgi.py
では application = get_wsgi_application()
としてモジュール変数にアサインしている。
ちょっと誤解していたので訂正。
- settings に
WSGI_APPLICATION
を指定していなければget_wsgi_application
が呼ばれるので、前回書いたとおりWSGIHandler
が使われる settings の
WSGI_APPLICATION
のデフォルト値はproj.wsgi.application
という風に生成されているwsgi.py
ではapplication = get_wsgi_application()
としてモジュール変数にアサインしている。- =
WSGIHandler
が使われる
つまり初期設定だとどちらでも WSGIHandler
が使われるということだった。
自分の理解が正しければ、このあたりまできたら次は WSGI application を動かすってどういうことなのかってところに行きそうなんだけど。そこまでわかってないのでまた今度。
メインループがなにをしているかをみる
読むモジュールは django.cre.servers.basehttp
。WSGIServer.run
メソッドをみる。
WSGIServer
の生成
threading
が有効であれば socketserver.ThreadingMixIn
を Mixin する様子。無効なら WSGIServer
のみつかう。
この WSGIServer
は django.core.servers.basehhtp
モジュールのクラス。抜粋してはるとこう
class WSGIServer(simple_server.WSGIServer, object): """BaseHTTPServer that implements the Python WSGI protocol""" request_queue_size = 10 def __init__(self, *args, **kwargs): if kwargs.pop('ipv6', False): self.address_family = socket.AF_INET6 super(WSGIServer, self).__init__(*args, **kwargs)
wsgiref.simple_server
の WSGIServer
を呼び出している。
ここをもう少しみていくとこういう継承になっている。
django.core.servers.basehttp#WSGIServer
wsgiref.simple_server#WSGIServer
http.server#HTTPServer
socketserver#TCPServer
つまり django -> wsgiref -> HTTPServer -> socket 通信レイヤーの TCPServer まで降りて行くことになる。
WSGIserver
の実行
- インスタンス作成
- setup
- serve_forever() でループに入る
おわりに
前に開発用サーバーを動かすというときに、たしかに Django が用意してくれたコマンドのサーバーがあるけど、なにをどこまでやっているかがわからなかった。このライブラリではどのレイヤーまで面倒をみてくれるかというのを知るとなにかと楽になる。