2012-06-15 10 views
5

Fui introducido en una base de código heredada para actualizarlo de Rails 2.4/Ruby 1.8.7 a Rails 3.1/Ruby 1.9.2. Mientras hacía esto, encontré un problema muy interesante que tardó 3 días en descubrirse. Quería dejarlo aquí tanto para darle un poco de jugo de Google a otra persona que vea el problema, como para hacer la pregunta: ¿Por qué?SystemStackError en el nivel de bastidor en Ruby 1.9.2, no 1.8.7

Básicamente, estaba viendo un SystemStackError en el nivel de bastidor cuando ejecuté mi aplicación. No pude obtener ninguna solicitud hasta que se produjo el error, y no pude depurarlo porque mi código nunca fue tocado. En el modo Desarrollo, podría ver gran parte del sitio, y de repente obtendría el SystemStackError cuando se golpeó la base de datos. Así que pensé que era una carga perezosa.

Cambie al modo de producción, y la excepción se produce en la primera solicitud. El servidor comienza normalmente, pero no hay solicitudes que lo completen, y mi código no se tocó.

de avance rápido demasiadas horas, y rastrearon el rastreo de un bucle en Rails (full gist):

/Users/john/.rvm/gems/[email protected]/gems/actionpack-3.1.6/lib/action_dispatch/routing/url_for.rb:102:in `initialize' 
/Users/john/.rvm/gems/[email protected]/gems/actionpack-3.1.6/lib/action_controller/metal.rb:140:in `initialize' 
/Users/john/.rvm/gems/[email protected]/gems/actionpack-3.1.6/lib/abstract_controller/rendering.rb:74:in `initialize' 
/Users/john/.rvm/gems/[email protected]/gems/actionpack-3.1.6/lib/abstract_controller/layouts.rb:301:in `initialize' 
/Users/john/.rvm/gems/[email protected]/gems/actionpack-3.1.6/lib/action_dispatch/routing/url_for.rb:103:in `initialize' 
/Users/john/.rvm/gems/[email protected]/gems/actionpack-3.1.6/lib/action_controller/metal.rb:140:in `initialize' 
/Users/john/.rvm/gems/[email protected]/gems/actionpack-3.1.6/lib/abstract_controller/rendering.rb:74:in `initialize' 
/Users/john/.rvm/gems/[email protected]/gems/actionpack-3.1.6/lib/abstract_controller/layouts.rb:301:in `initialize' 
/Users/john/.rvm/gems/[email protected]/gems/actionpack-3.1.6/lib/action_dispatch/routing/url_for.rb:103:in `initialize' 
/Users/john/.rvm/gems/[email protected]/gems/actionpack-3.1.6/lib/action_controller/metal.rb:140:in `initialize' 
/Users/john/.rvm/gems/[email protected]/gems/actionpack-3.1.6/lib/abstract_controller/rendering.rb:74:in `initialize' 
/Users/john/.rvm/gems/[email protected]/gems/actionpack-3.1.6/lib/abstract_controller/layouts.rb:301:in `initialize' 
/Users/john/.rvm/gems/[email protected]/gems/actionpack-3.1.6/lib/action_dispatch/routing/url_for.rb:103:in `initialize' 
/Users/john/.rvm/gems/[email protected]/gems/actionpack-3.1.6/lib/action_controller/metal.rb:140:in `initialize' 
/Users/john/.rvm/gems/[email protected]/gems/actionpack-3.1.6/lib/abstract_controller/rendering.rb:74:in `initialize' 
/Users/john/.rvm/gems/[email protected]/gems/actionpack-3.1.6/lib/abstract_controller/layouts.rb:301:in `initialize' 
/Users/john/.rvm/gems/[email protected]/gems/actionpack-3.1.6/lib/action_dispatch/routing/url_for.rb:103:in `initialize' 
/Users/john/.rvm/gems/[email protected]/gems/actionpack-3.1.6/lib/action_controller/metal.rb:238:in `new' 
/Users/john/.rvm/gems/[email protected]/gems/actionpack-3.1.6/lib/action_controller/metal.rb:238:in `block in action' 
/Users/john/.rvm/gems/[email protected]/gems/actionpack-3.1.6/lib/action_dispatch/routing/route_set.rb:71:in `call' 
/Users/john/.rvm/gems/[email protected]/gems/actionpack-3.1.6/lib/action_dispatch/routing/route_set.rb:71:in `dispatch' 
/Users/john/.rvm/gems/[email protected]/gems/actionpack-3.1.6/lib/action_dispatch/routing/route_set.rb:35:in `call' 
/Users/john/.rvm/gems/[email protected]/gems/rack-mount-0.8.3/lib/rack/mount/route_set.rb:152:in `block in call' 
/Users/john/.rvm/gems/[email protected]/gems/rack-mount-0.8.3/lib/rack/mount/code_generation.rb:96:in `block in recognize' 
/Users/john/.rvm/gems/[email protected]/gems/rack-mount-0.8.3/lib/rack/mount/code_generation.rb:68:in `optimized_each' 
/Users/john/.rvm/gems/[email protected]/gems/rack-mount-0.8.3/lib/rack/mount/code_generation.rb:95:in `recognize' 
/Users/john/.rvm/gems/ruby-[email protected]/gems/rack-mount-0.8.3/lib/rack/mount/route_set.rb:141:in `call' 
/Users/john/.rvm/gems/[email protected]/gems/actionpack-3.1.6/lib/action_dispatch/routing/route_set.rb:538:in `call' 
/Users/john/.rvm/gems/[email protected]/gems/omniauth-1.1.0/lib/omniauth/builder.rb:48:in `call' 
... 

Lo que vemos aquí es la bicicleta sistema de metal.rb a url_for.rb a layouts.rb a rendering.rb a metal.rb a url_for.rb, etc

Después de un considerable esfuerzo, rastreé esto a la siguiente línea en la parte superior de un archivo de modelo (like so):

include ActionView::Helpers::UrlHelpers 

Nota, esto no está dentro de la clase, es a nivel de módulo.

Lo interesante es que esto funciona en Ruby 1.8.7 pero causa un SystemStackError en Ruby 1.9.2.

He creado un Github repository illustrating this behavior.

Si toma este repositorio y ejecuta la rama ruby18, puede cargar una página. Si ejecuta la rama ruby19, obtendrá un SystemStackError en cualquier solicitud (cualquier solicitud donde se cargue Widget, lo ejecutará en producción y no se cargará de forma diferida).

Entonces, ¿alguien sabe por qué?

Quiero decir, me imagino que tiene algo que ver con la forma en que Ruby 1.9 carga módulos, ya que no parece ser un problema causado por el núcleo de Rails. Mi principal preocupación es si esto es solo un problema esotérico causado por prácticas de programación perezosa en la base de código o si es un indicador de un problema más profundo, ya sea en Ruby o Rails.

+0

Tengo el mismo problema. Para agregar un poco más de contexto, si lanzo todo el conjunto de pruebas, he cometido este error, pero si ejecuto una única prueba, funciona sin problemas. ¿Alguna noticia sobre la resolución? thx – gicappa

+1

La resolución para mí fue eliminar el '' 'include ActionView :: Helpers :: UrlHelpers''' que causaba el bucle. Si no tienes eso, mi sospecha, sin saber nada sobre tu código, es que hay otra cosa similar. – JohnMetta

+0

Gracias, descubrí que tenía un include ActionView :: Helpers :: TagHelper en una prueba. – gicappa

Respuesta

1

Esto se parece a Bug 3144, diciendo que haga referencia al ayudante directamente.

Rails.application.routes.url_helpers 
+0

Lo busqué, pero no lo encontré. Gracias por vincular eso aquí. – JohnMetta

Cuestiones relacionadas