猫型エンジニアのブログ

プログラム/ネットワーク系の技術関連をまとめたページです 

BaseServerの仕組み

 Python上で動作する様々なフレームワークやライブラリを見ていると、よくサーバがつかわれているのがよく見られます。そこで、Python上でサーバがどのように実装されているのかを見てみました。ライブラリのコードを読むと勉強になるといいますが、確かにその通りだと思います。

源流を辿っていくと…

 Pythonのライブラリを辿っていくと、socketserverというモジュールにたどり着きます。ソースコード冒頭に記載されているように、アドレスファミリー(IPソケット/Unixドメインソケット)/ソケットタイプ(TCPUDP)/マルチリクエスト処理(同期・マルチプロセス・マルチスレッド)などの様々な処理の実装に対応しています。

 ドキュメント(必読、すごくためになります)記載されている通り、BaseServerがすべてのサーバの基底クラスになっており、最低限のインタフェースしか定義されていません。クライアントのリクエストに対してどのような処理をするかに関しては、ユーザがハンドラーとして具体的に実装することになります。

BaseServerのメソッド

 いくつものメソッドが定義されていますが、大きく分けてサーバの制御に関するメソッド群と、リクエストの処理に関わるメソッド群に分類できます。メソッドの名前をみているだけで大体何をしているかが理解できます。たとえどのような種類のサーバでも、以下のメソッド群で必要な機能をほぼ網羅していると考えるととても興味深いです。

サーバの制御に関するメソッド
  • server_activate
  • server_close
  • serve_forever
  • shutdown
  • service_actions
リクエストの処理に関するメソッド
  • handle_request
  • _handle_request_noblock
  • verify_request
  • process_request
  • finish_request
  • shutdown_request
  • close_request
  • handle_timeout
  • handle_error

BaseServerの処理の流れ

 最初にアドレスとユーザ定義のハンドラーを引数として与えられて、サーバがインスタンス化されます。

 次にserver_forerverでクライアントからのリクエストの待ち受けのループに入ります。BaseServerではセレクタを用いてノンブロッキングIOを実装しています。

 server_forever内でリクエスト受信時に呼び出される処理の中で、ユーザ定義のハンドラをインスタンス化します。インスタンス化する際にクライアントのリクエストを引数として渡して、リクエストに応じた処理をさせます。