Rails 2.4/Ruby 1.8.7 から Rails 3.1/Ruby 1.9.2 にアップグレードするために、レガシー コードベースを使用するようになりました。これを行っているときに、理解するのに 3 日かかった非常に興味深い問題を見つけました。ここにドロップして、問題に直面している他の誰かに Google の力を与え、次の質問をしたいと思いました。なぜですか?
基本的にSystemStackError
、アプリを実行しているときにラック レベルで が表示されていました。エラーが発生する前にリクエストを取得できず、コードに手を加えていなかったため、デバッグできませんでした。開発モードでは、サイトの大部分を表示できましたがSystemStackError
、データベースがヒットしたときに突然取得しました。だから私はそれが遅延読み込みであると考えました。
本番モードに切り替えると、最初のリクエストで例外が発生します。サーバーは正常に起動しますが、リクエストは通過せず、コードは変更されませんでした。
あまりにも多くの時間を早送りし、Rails のループへのトレースバックを追跡しました (完全な要点):
/Users/john/.rvm/gems/ruby-1.9.2-p320@qstream-ruby19/gems/actionpack-3.1.6/lib/action_dispatch/routing/url_for.rb:102:in `initialize'
/Users/john/.rvm/gems/ruby-1.9.2-p320@qstream-ruby19/gems/actionpack-3.1.6/lib/action_controller/metal.rb:140:in `initialize'
/Users/john/.rvm/gems/ruby-1.9.2-p320@qstream-ruby19/gems/actionpack-3.1.6/lib/abstract_controller/rendering.rb:74:in `initialize'
/Users/john/.rvm/gems/ruby-1.9.2-p320@qstream-ruby19/gems/actionpack-3.1.6/lib/abstract_controller/layouts.rb:301:in `initialize'
/Users/john/.rvm/gems/ruby-1.9.2-p320@qstream-ruby19/gems/actionpack-3.1.6/lib/action_dispatch/routing/url_for.rb:103:in `initialize'
/Users/john/.rvm/gems/ruby-1.9.2-p320@qstream-ruby19/gems/actionpack-3.1.6/lib/action_controller/metal.rb:140:in `initialize'
/Users/john/.rvm/gems/ruby-1.9.2-p320@qstream-ruby19/gems/actionpack-3.1.6/lib/abstract_controller/rendering.rb:74:in `initialize'
/Users/john/.rvm/gems/ruby-1.9.2-p320@qstream-ruby19/gems/actionpack-3.1.6/lib/abstract_controller/layouts.rb:301:in `initialize'
/Users/john/.rvm/gems/ruby-1.9.2-p320@qstream-ruby19/gems/actionpack-3.1.6/lib/action_dispatch/routing/url_for.rb:103:in `initialize'
/Users/john/.rvm/gems/ruby-1.9.2-p320@qstream-ruby19/gems/actionpack-3.1.6/lib/action_controller/metal.rb:140:in `initialize'
/Users/john/.rvm/gems/ruby-1.9.2-p320@qstream-ruby19/gems/actionpack-3.1.6/lib/abstract_controller/rendering.rb:74:in `initialize'
/Users/john/.rvm/gems/ruby-1.9.2-p320@qstream-ruby19/gems/actionpack-3.1.6/lib/abstract_controller/layouts.rb:301:in `initialize'
/Users/john/.rvm/gems/ruby-1.9.2-p320@qstream-ruby19/gems/actionpack-3.1.6/lib/action_dispatch/routing/url_for.rb:103:in `initialize'
/Users/john/.rvm/gems/ruby-1.9.2-p320@qstream-ruby19/gems/actionpack-3.1.6/lib/action_controller/metal.rb:140:in `initialize'
/Users/john/.rvm/gems/ruby-1.9.2-p320@qstream-ruby19/gems/actionpack-3.1.6/lib/abstract_controller/rendering.rb:74:in `initialize'
/Users/john/.rvm/gems/ruby-1.9.2-p320@qstream-ruby19/gems/actionpack-3.1.6/lib/abstract_controller/layouts.rb:301:in `initialize'
/Users/john/.rvm/gems/ruby-1.9.2-p320@qstream-ruby19/gems/actionpack-3.1.6/lib/action_dispatch/routing/url_for.rb:103:in `initialize'
/Users/john/.rvm/gems/ruby-1.9.2-p320@qstream-ruby19/gems/actionpack-3.1.6/lib/action_controller/metal.rb:238:in `new'
/Users/john/.rvm/gems/ruby-1.9.2-p320@qstream-ruby19/gems/actionpack-3.1.6/lib/action_controller/metal.rb:238:in `block in action'
/Users/john/.rvm/gems/ruby-1.9.2-p320@qstream-ruby19/gems/actionpack-3.1.6/lib/action_dispatch/routing/route_set.rb:71:in `call'
/Users/john/.rvm/gems/ruby-1.9.2-p320@qstream-ruby19/gems/actionpack-3.1.6/lib/action_dispatch/routing/route_set.rb:71:in `dispatch'
/Users/john/.rvm/gems/ruby-1.9.2-p320@qstream-ruby19/gems/actionpack-3.1.6/lib/action_dispatch/routing/route_set.rb:35:in `call'
/Users/john/.rvm/gems/ruby-1.9.2-p320@qstream-ruby19/gems/rack-mount-0.8.3/lib/rack/mount/route_set.rb:152:in `block in call'
/Users/john/.rvm/gems/ruby-1.9.2-p320@qstream-ruby19/gems/rack-mount-0.8.3/lib/rack/mount/code_generation.rb:96:in `block in recognize'
/Users/john/.rvm/gems/ruby-1.9.2-p320@qstream-ruby19/gems/rack-mount-0.8.3/lib/rack/mount/code_generation.rb:68:in `optimized_each'
/Users/john/.rvm/gems/ruby-1.9.2-p320@qstream-ruby19/gems/rack-mount-0.8.3/lib/rack/mount/code_generation.rb:95:in `recognize'
/Users/john/.rvm/gems/ruby-1.9.2-p320@qstream-ruby19/gems/rack-mount-0.8.3/lib/rack/mount/route_set.rb:141:in `call'
/Users/john/.rvm/gems/ruby-1.9.2-p320@qstream-ruby19/gems/actionpack-3.1.6/lib/action_dispatch/routing/route_set.rb:538:in `call'
/Users/john/.rvm/gems/ruby-1.9.2-p320@qstream-ruby19/gems/omniauth-1.1.0/lib/omniauth/builder.rb:48:in `call'
...
ここに表示されているのは、システムが からmetal.rb
へurl_for.rb
からlayouts.rb
へなどrendering.rb
を循環しているmetal.rb
ことです。url_for.rb
かなりの労力を費やした後、モデルファイルの先頭にある次の行までこれを追跡しました(so のように):
include ActionView::Helpers::UrlHelpers
これはクラス内ではなく、モジュール レベルであることに注意してください。
興味深いことに、これは Ruby 1.8.7 では機能しますがSystemStackError
、Ruby 1.9.2 では a が発生します。
この動作を示す Github リポジトリを作成しました。
このリポジトリを取得してruby18
ブランチを実行すると、ページをロードできます。ブランチを実行すると、ruby19
すべてのリクエストで SystemStackError が発生します (ウィジェットがロードされているすべてのリクエストは、本番環境で実行され、遅延ロードされません)。
それで、誰かが理由を知っていますか?
つまり、Ruby 1.9 がモジュールをロードする方法と関係があると思います。Rails コアが原因の問題ではないようです。私の主な関心事は、これがコードベースでの怠惰なプログラミング慣行によって引き起こされた単なる難解な問題なのか、それとも Ruby または Rails のいずれかのより深い問題へのポインタなのかということです。