GAE HackathonでJRuby on Railsの一言掲示板つくった
Winノートには開発用のツールが何にも入ってなかったのでJavaやらgitやらなんやかやインストールするだけで持ち時間半分くらい消費して心が折れかかってたけど、最終的に作業時間が一時間追加されたこともあってなんとか動作。
ほとんどが自宅のiMacで一度やってる作業なのにこんなにセットアップに時間かかるなんて、Vista恐るべし。
http://itrain.appspot.com/
一応、JRubyで動いてる証拠として
e:Time.now
みたいにe:を頭に書けばRubyのステートメントが実行されるようにしといた。ホントはThread内で$SAFE上げて実行したかったんだけど流石にThreadはGAEが使わせてくれないようなので、JRuby&GAE&みなさんを全面的に信用して
if comment_body =~ /^e:(.+)$/ eval($1) end
みたいなうんこ実装。問題あったら即消す。
では以下、皆さんが私の二の轍踏まないようにはまった場所を書いときます。良かったら参考にどうぞ。
時間切れ
エラーメッセージには大して情報はないし、コンソールのログには何にも出ない。何かと思ってたんだけど、これ処理に時間がかかりすぎて(たぶん30秒)GAEに殺されたときに出るエラーみたい。まれに成功したりするもんで、なんなのか気づくのにえらい時間掛かった。
で、困ったときのYARBLということで、ソース見てるとappengine-web.xmlに次のような記述を発見。
<property name="jruby.compile.mode" value="JIT"/> <!-- JIT|FORCE|OFF --> <property name="jruby.compile.fastest" value="true"/> <property name="jruby.compile.frameless" value="true"/> <property name="jruby.compile.positionless" value="true"/> <property name="jruby.compile.threadless" value="false"/> <property name="jruby.compile.fastops" value="false"/> <property name="jruby.compile.fastcase" value="false"/> <property name="jruby.compile.chainsize" value="500"/> <property name="jruby.compile.lazyHandles" value="false"/> <property name="jruby.compile.peephole" value="true"/>
明らかにこの辺でパフォーマンス上がるようにJRubyのプロパティを設定してるので、とりあえず何も考えずに自分のappengine-web.xmlにコピペしたところ、一度目はほぼ確実に時間切れでエラーになるものの、とりあえずそれでメモリには乗っかってくれるようで、リロードすれば無事表示される感じに。
YARBLの人が初回の読み込みが遅いって強調してたのがよく分かった。
ログ出力
さらにその辺で例外吐いたのに伴ってログ出力周りでも「ファイルに書き込めねー」みたいなエラーが出たんだけど、これもYARBL見て解決。config/environments/production.rb
config.cache_classes = true class ServletContextLogger def debug(progname = nil, &block) log(:DEBUG, progname, &block) end # ..snip.. def log(severity, progname, &block) message = progname || block.call $servlet_context.log("#{severity}: #{message}") end end config.logger = ServletContextLogger.new
セッション
当たり前だけどGAEはActiveRecord使えないのでActiveRecord session storeも使えない。これもYARBLの人が解決してくれてる。Olabiniサイコー。lib/big_table_servlet_store.rb取って来て、config/envieronmnt.rbに以下みたいなのを追加。
require 'big_table_servlet_store' Rails::Initializer.run do |config| # ..snip.. config.action_controller.session_store = :big_table_servlet_store end
バージョン
あと最後にこれは気のせいかもしれないけど、以前の「I'm JRuby on Rails」を生かしたまま開発する為に、今回のはappengine-web.xmlでバージョンを2に設定して、2.itrain.appspot.com みたいにアクセスしてたんだけど、これだとリロードしても成功してくれなかった。
諦めてコンソールでデフォルトバージョンを2に設定して、itrain.appspot.com で確認するようにしたら改善した気がする。デフォルトに設定されてるバージョンはパフォーマンス少しよかったりするんだろうか。