2009-10-21 24 views
7

Tengo una aplicación de Rails en la que un pequeño número de acciones requiere un tiempo de cálculo significativo. En lugar de pasar por la complejidad de administrar estas acciones como tareas en segundo plano, descubrí que puedo dividir el procesamiento en múltiples hilos y al usar JRuby con un servidor de varios núcleos, puedo asegurarme de que todos los hilos se completen en un tiempo razonable. (El cliente ya ha expresado un gran interés en mantener este enfoque frente a las tareas en segundo plano.)Iniciar sesión en hilos en una aplicación de Rails

El problema es que escribir en el registrador Rails no funciona dentro de estos hilos. Nada aparece en el archivo de registro. Encontré algunas referencias a este problema pero ninguna solución. No me importaría insertar puts en mi código para ayudar con la depuración, pero stdout parece ser devorado por el servidor de glass gem gem app.

¿Alguien ha realizado con éxito el inicio de sesión dentro de un subproceso de rubí de Rails sin crear un nuevo registro cada vez?

+0

Actualización: Encontré que los hilos de puesto se muestran en el archivo de registro glassfish. No estoy seguro de por qué no vi esto antes; Es posible que lo haya probado originalmente en un hilo generado por otro hilo (no principal). De todos modos, para fines de depuración, estoy viendo escrituras en STDOUT en el archivo de registro, así que estoy contento. –

Respuesta

4

Me estaba rascando la cabeza con el mismo problema. Para mí, la respuesta fue la siguiente:

Thread.new do 
    begin 
    ... 
    ensure 
    Rails.logger.flush 
    end 
end 
+0

¡Se ve bien! ¡Gracias! –

+0

No funciona para mí, usando EM – skrat

0

Entiendo su preocupación acerca de las tareas en segundo plano, pero recuerde que desenrollar hilos en Rails puede ser algo aterrador. El marco no incluye disposiciones para el multihilo, lo que significa que debe tratar todos los objetos de Rails como no seguros para subprocesos. Incluso la conexión a la base de datos se vuelve engañosa.

En cuanto al registrador: La clase de registrador estándar de Ruby debe ser segura para subprocesos. Pero incluso si Rails usa eso, no tienes control sobre lo que la aplicación Rails le está haciendo. Por ejemplo, el mecanismo de evaluación comparativa "silenciará" al registrador al cambiar los niveles.

Evitaría usar el registrador de rieles. Si desea usar los hilos, cree un nuevo registrador dentro del hilo que registra los mensajes para esa operación. Si no desea crear un nuevo registro para cada subproceso, también puede intentar crear un objeto de registro seguro para subprocesos en el tiempo de ejecución al que pueda acceder cada subproceso.

En su lugar, probablemente tenga otra mirada a las soluciones de trabajo en segundo plano. Mientras DRb parece una pesadilla, "bj" parece agradable y fácil; aunque requirió algún trabajo para hacerlo funcionar con JRuby. También existe la alternativa de utilizar un programador Java de JRuby, ver http://www.jkraemer.net/2008/1/12/job-scheduling-with-jruby-and-rails

+0

Gracias por la información y las sugerencias, pero en este punto me quedaré con el enfoque de enhebrado ya que funciona bien, excepto para el registro. No utilizo gemas/complementos cuestionables en ninguno de los subprocesos y tengo cuidado con el uso de mutexes para evitar condiciones de carrera. Mi interés en utilizar el registrador de Rails era fácil de depurar y me las he arreglado para solucionarlo al usar hebras solo si JRUBY_VERSION está definido y ejecuta el mismo código secuencialmente. ¡Gracias de cualquier manera! –

Cuestiones relacionadas