テックランチ
業務の合間をぬって、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 の発想に近いな、と思ってにんまり。
顔なじみの方の投稿です。^^)