Tweet2009年05月10日PassengerでRackアプリを動かす昨日のネタではRackで簡単なアプリを作ってそれを複数立ち上げたThinで動かしつつ、表のApacheからmod_proxy_balancerで適当にプロキシしてやるって構成にした。Railsとかでもよくやるので慣れてるし、扱い易いので好きな構成だ。今回の遊びでちょっとやってみたかったけことがある。何かというと、Passengerの導入。mod_railsとかmod_rackとか呼ばれてるアレ。スタンドアロンのサーバではなくてApacheやnginxに組み込んで使うタイプで、パフォーマンスもそれなりに良いし使い易いという話を聞いてたので気になってはいた。Rails使わなくなってからなかなか試してみる機会がなかったので、この際ついでだ、とやってみることにした。設定は簡単インストールについてはPassengerのページでも見てもらうとします。8.04)ではapt-getでさくっと入った。次のような構成のRackアプリができてたとする。この状態でrackupすれば普通に動くのが前提。view/で、rackapp.example.orgってのでアクセスすると上のアプリに処理が移るようにしたいとする。/var/www/rackapp以下にpublic、tmpってディレクトリを作る。publicはhtmlとかcssとかの静的ファイルを置く場所。tmpには、あとで説明するけど、restart.txtってのを置いておく。restart.txtそこまで用意できたら次はApacheの設定。/</VirtualHost>これだけ。指定をしなければこれでRACK_ENV=productionでアプリが起動する。細かい指定はできるけど、まぁそれは必要になったときにいじればいいよねとりあえず。tmp/restart.txtとかやってrestart.txtのタイムスタンプを更新してやるとPassengerがアプリを再読み込みしてくれる。なんだよマジ簡単じゃんよー、とか思ってたら甘かった。これでブラウザからアクセスしてみたら、全く何も表示されない。config.ruでRack::Lintをuseしてるんだけど、ログ見たらそいつが何か警告出して処理を止めてる。うーん、だけど、全く見に覚えのない警告なので、困惑しつつRack::Lintを外してみる。見てると、アプリのcallメソッドに渡されたenvからRack::Requestを作るときにこける様子。なになに、env['rack.input']にrewindメソッドが無い...?色々調べてたら、Rack::RequestはrewindできるIOオブジェクトが必要なんだけど、PassengerはrewindできないIOを渡してくるらしい。Rackの開発グループでも議論になってる様子。これRackベースのWAFとか作ってると結構致命的だよなー。rewindが無いと駄目なら、rewindできるオブジェクトにしちゃえとまぁつまりそういう話なわけですよ。Passengerが渡してくるIOオブジェクトがrewindできないなら、rewindできるIOオブジェクトに変換するなりラップするなりしてしまえばいいや、と。同じこと考えてる人もいるみたいだし、そもそもその人が何を参考にしてるかというとRailsのActionControllerの実装だったりする。いうわけで、それにならってとりあえずこんなミドルウェアを作ってみた。NetaKit::Resource::Kanojo.newendNetaKit、はfaultier.jpで動いてるアプリのnamespaceなので特に気にしない方向で。こんな感じにしてやると、rack.inputがrewindできないIOだったときはStringIOに変換してからアプリに渡してくれるようになる。やってみたらこれでちゃんと動くようになった。このままだと入力を使う使わないに拘わらず(例えばRack::Responseを生成せずにenvを生で扱い、かつinputを読む必要のない処理だけをやるようなミドルウェアとかを通してるときにでも)毎回inputをreadしちゃってアレげなので、ちゃんとやろうと思ったら何かのオブジェクトでラップしてやって呼ばれたときに変換かけるようにする方がいいかも。さっきのCloudKitだとこんな風に実装してるとか。上に書いたのでも動くっちゃ動くのでお試し程度なら十分だけど。お手軽感は確かにというわけで意外に手間どったPassenger対応だったんだけど、rack.inputの問題を除けば簡単に設定できて中々良い。立ち上げるプロセス数の調整とかもApacheが勝手にやってくれるわけだし、静的ファイルはアプリ通さないで返すようにするのにも特に設定が要らないのも楽だ。動かすのがApacheだけなのも余計なこと考えないで済むしいいな。BenchでPassengerとThin+mod_proxy_balancerとのパフォーマンス比べてみたんだけど、ぶっちゃけ殆ど差はない。言っても/resource/kanojoにひたすらGETリクエスト送っても殆ど静的なレスポンスを返すだけなので本当に参考程度。同時アクセス数を増やしてみたら若干数値が違ってたけど、Thinの立ち上げてるプロセス数次第で変わってくるだろうし、どうせ実運用になるとPassengerの場合でももう一段フロント立ててごにょごにょやるだろうからなぁ。RailsとかMerbとかでがちっとアプリ組んで、mongrel、lighttpd、WEBrick、fcgiとか色々試してみないと何とも言い難い。個人で作ったものくらいだったらPassengerのがやること少なくてお手軽かも、くらいには思った。あとまぁレンタルサーバだったら各自アプリケーションサーバ起動させるとか許さないだろうけど、Apacheに組み込めるんなら入れといてくれるところとかありそう。Passengerで運用してみよう。関係ないけどrack.input問題調べてる最中に偶然辿り付いたCloudKitがちょっと気になる。面白そうだし、atomserver作るのに参考になりそう。あとでいじってみよう。彼女のステータスを返す日々着実にバカな方にバカな方に向かってるのを実感してるfaultierです、みなさんお久しぶり。一昨日あたりに見かけた「彼女がいないことをステータスコード404で表わす」ってのが大変ツボに入ったので、今日はせっかくだから実際にそれを実装してみたよ。なんと以下のURLをGETすると「faultierの彼女」ってリソースがいまどんなステータスなのか返してくれるんだ。http://faultier.jp/resource/kanojo...まぁ俺に彼女がいるかどうかなんて瑣末なことはどうでも良くて、一応これGET/POST/PUT/DELETEに対応してて、それぞれ違うレスポンスを返すように作ってあるので、生まれついてのHTTPクライアントな感じの少年少女紳士淑女な方々はいろんなリクエストを送って「リソース:faultierの彼女」をいじってみるといいと思うんだ。操作しようが何も起きませんが。何、あんま使わないからってサボってGETとPOSTしか実装してない?しょうがないやつだな、GETするときにURLの末尾に/putとか/deleteとか入れてみなよ。それっぽい動きするから。teapot」とかも実装する予定。あ、あとちなみに、GETするときにmode=prevとかmode=nextってクエリを付けると「前の彼女」「未来の彼女」についての情報も返ってくる。追記:418も実装した。ついでに多少ステータスコードをいじった。そのリクエストにそのレスポンスは普通無いだろ、みたいのがあるとあれなので。あと、HEADを忘れてたのでHEADも対応した。Rack可愛いよRackネタはネタとして置いとくとして、今回はこれをRackとHamlを使って作ってみた。何でかというと、今Ruby版Atompub::Serverみたいの作ってて、RailsやMerbのプラグインもそのうち書くつもりではいるんだけど、まず単体でサクっと動くの作りたいなと思っていろいろいじってるところだったから。Hamlは興味はあったんだけど中々触る機会がなかったので、ついで。なんというか、Rackは素敵だなぁ。この程度のものを作るのにちゃんとしたWAFを使うのもなんだかゴキブリ退治に対戦車ミサイル持ち出すみたいで気がひけるんだけど、かといってCGIってのもねぇ、みたいなときにもとても良い。簡単な認証とかロギングとかセッションとかは添付のミドルウェア使えば実現できちゃうし、WEBrickとかで簡単にローカル環境で開発サーバ作れちゃうのも魅力的。そんでもって深く考えなくてもWEBrik、thin、mongrel、fcgi、Passengerと色んな環境に対応できちゃうのも素敵だ(というかそれは話が逆で、そのためのインターフェースライブラリなんだけども)。なによりRack::Testが便利すぎる。こんなしょうもないアプリでもちゃんとSpec書いたんだぜ、あんまり簡単だったから。ハムは食べたいけどもHamlの方は、なんというか、結構微妙。いやまぁ、確かにすっきりシンプルなテンプレートが書けるんだけど、普段見なれてるHTMLから乖離しすぎててちょっと抵抗あるかも。学習コスト考えたら素のHTMLとRubyをそのまま書けるerbやその派生/改善版のテンプレートエンジンのがよっぽどとっつきやすい気がする。一人でやってるときはともかく、デザイナーやマークアッパーとの分業で仕事してると、これ出力がどうなるか想像しながらやんなきゃならなくて作業しづらいんじゃないのかなーとか思ってしまう。言え不思議な魅力もあるのも確かで、文句言いながら書いてたけど数分後にはなんとなく慣れてしまった。趣味でなんか作るときにはしばらく使ってみようかなと思ってたりする。ところで一応言っとくけど、あそこからエントリーしても別にデータとか保存してないしメール送ったりもしないので、安心して彼女の名乗りを上げるといいよ!まぁ本当に名乗りたければあんなとこで慎しやかに名乗られても困るけど、いないよねそんな人。