テックランチ

業務の合間をぬって、Pyxis テックランチをしました。
話題はRoutes の Application 間共有の問題。Pyxis ではフロントと管理画面を別WSGIApplication として実装することを検討しているのですが、これがなかなか難しいです。

Routes の仕組み

Routes の主な役割は、以下の2つです。

  • Mapper : PATH_INFO を元に起動するAction を振り分ける
  • Generator : URLを生成する

RoutesMiddleware は environ['PATH_INFO'] や map オブジェクトを入力として、environ['wsgiorg.routing_args'] にマッピング情報を、environ['routes.route'] にroute オブジェクトを格納します。Routes が格納したマッピング情報を元にPylons は Controller の Action を呼び出し、url_for はURLを生成します。

問題は、Routes は1つの(マクロな)WSGIApplication で1つだけ利用され、その情報が1つの(マクロな)WSGIApplication の中で閉じているということです。

url_for の拡張

url_for を利用するユーザからすると

h.url_for(application='news', controller='show', id=1)

のように使いたいです。a

Routes のApplication 間共有

複数のWSGIApplication をまたがったrouting 情報の共有をするために、
テックランチでは様々なアイデアが出ましたが、大きく分けると次の2つに大別されます。

  • WSGIApplication に階層構造を持たせ、上位のWSGIApplicatin に複数のWSGIApplication をぶらさげる。各WSGIApplication は、上位のWSGIApplication を介して、routing 情報等を共有する
  • 複数の独立したWSGIApplication として実装して、各WSGIApplication 間で通信したり、オブジェクトを共有する仕組みを用意する

前者はさらに、「route オブジェクトを複数持つ方法」と「route オブジェクトを全体で1つだけもつ方法」に分かれます。

また後者では、以下のような実装が提案されました。

  • XML通信(やりたくない!)
  • 他のWSGIApplication のmap オブジェクトとPATH情報を入力として、他のWSGIApplication をシミュレートし、互いのroute オブジェクトを取得する
    • パフォーマンスに問題。また、得られるroute オブジェクトはシミュレートによって生成されたものなので、厳密には相手のアプリのroute オブジェクトそのものではない。route 以外で何か処理をしていた場合に、それを正確に再現できない。
  • Pylons における g オブジェクトより上位のglobal 変数(異なるWSGIApplication間でも共有できるGlobal オブジェクト)を保持する仕組みを用意して、そこに各WSGIApplication のroute オブジェクトを格納する(python の global 変数で良い?)

とりあえずの、まとめ

個人的には、WSGIApplication の柔軟性を生かすために、複数のWSGIApplication のルースカップリングを目指したいです。そのためには、後者がいいかな。

いろいろ調べていたら、 Componentized Application Development の発想に近いな、と思ってにんまり。
顔なじみの方の投稿です。^^)

junya.