ruby-on-rails - ejemplos - schedule cron rails
¿Prácticas recomendadas para que la aplicación Rails ejecute una tarea larga en segundo plano? (14)
Está el nuevo Growl4Rails ... que es para este caso de uso específico (entre otros también).
http://www.writebetterbits.com/2009/01/update-to-growl4rails.html
Tengo una aplicación de Rails que desafortunadamente después de una solicitud a un controlador, tiene que hacer algunos cálculos que toman un tiempo. ¿Cuáles son las mejores prácticas en Rails para proporcionar retroalimentación o progreso en una tarea o solicitud de larga ejecución? Estos métodos de control generalmente duran más de 60 segundos.
No me preocupa el lado del cliente ... Estaba planeando tener una solicitud de Ajax cada segundo y mostrar un indicador de progreso. Simplemente no estoy seguro de las mejores prácticas de Rails, ¿creo un controlador adicional? ¿Hay algo inteligente que pueda hacer? Quiero que las respuestas se centren en el lado del servidor usando solo Rails.
Gracias de antemano por tu ayuda.
Editar:
Si es importante, la solicitud http es para archivos PDF. Luego tengo Rails en conjunto con Ruport generar estos PDF. El problema es que estos archivos PDF son muy grandes y contienen una gran cantidad de datos. ¿Sigue teniendo sentido usar una tarea de fondo? Supongamos que un PDF promedio tarda aproximadamente de un minuto a dos minutos. ¿Esto hará que mi aplicación Rails no responda a cualquier otra solicitud del servidor durante este tiempo?
Editar 2:
De acuerdo, después de una investigación más exhaustiva, parece que mi aplicación Rails no responde a ninguna otra solicitud HTTP después de que una solicitud entra para un PDF grande. Entonces, supongo que la pregunta ahora es: ¿Cuál es el mejor mecanismo de enhebrado / fondo para usar? Debe ser estable y mantenido. Estoy muy sorprendido de que Rails no tenga algo como esto integrado.
Editar 3:
He leído esta página: http://wiki.rubyonrails.org/rails/pages/HowToRunBackgroundJobsInRails . Me encantaría leer sobre varias experiencias con estas herramientas.
Editar 4:
Estoy usando Passenger Phusion "modrails", si es que importa.
Editar 5:
Estoy usando Windows Vista 64 bit para mi máquina de desarrollo; sin embargo, mi máquina de producción es Ubuntu 8.04 LTS. ¿Debo considerar cambiar a Linux para mi máquina de desarrollo? ¿Las soluciones presentadas funcionarán en ambos?
Esto realmente suena como algo que debería tener un proceso en segundo plano en lugar de una instancia de aplicación (pasajero / mestizo), de esa manera su aplicación puede seguir haciendo lo que se supone que debe hacer, atendiendo solicitudes, mientras que una tarea de fondo de algún tipo, Workling es bueno, maneja el número de crujidos. Sé que esto no trata el tema del progreso, pero a menos que sea absolutamente esencial, creo que es un precio pequeño a pagar.
Puede hacer que un usuario haga clic en la acción requerida, hacer que esa acción pase la solicitud a la cola de Workling y que le envíe algún tipo de notificación al usuario cuando se complete, tal vez un correo electrónico o algo así. No estoy seguro de lo práctico de eso, solo de pensar en voz alta, pero mi punto es que realmente parece que debería ser una tarea de fondo de algún tipo.
Tengo un sitio de gran volumen que genera muchos archivos CSV grandes. Estos a veces tardan varios minutos en completarse. Yo hago lo siguiente:
- Tengo una tabla de trabajos con detalles del archivo solicitado. Cuando el usuario solicita un archivo, la solicitud va en esa tabla y lleva al usuario a una página de "estado del trabajo" que enumera todos sus trabajos.
- Tengo una tarea de rake que ejecuta todos los trabajos pendientes (un método de clase en el modelo de trabajo).
- Tengo una instalación separada de rieles en otra caja que maneja estos trabajos. Esta casilla solo hace trabajos, y no es accesible al mundo exterior.
- En este cuadro separado, un trabajo cron ejecuta todos los trabajos pendientes cada 60 segundos, a menos que los trabajos aún se estén ejecutando desde la última invocación.
- La página de estado del trabajo del usuario se actualiza automáticamente para mostrar el estado del trabajo (que se actualiza en el cuadro de trabajos cuando el trabajo se inicia, se ejecuta y luego finaliza). Una vez que el trabajo está hecho, aparece un enlace al archivo de resultados.
Puede ser demasiado pesado si solo planea tener uno o dos funcionando a la vez, pero si quiere escalar ... :)
Uso Background Job ( http://codeforpeople.rubyforge.org/svn/bj/trunk/README ) para programar tareas. Estoy construyendo un pequeño sitio de administración que permite a los administradores del sitio ejecutar todo tipo de cosas que usted y yo ejecutamos desde la línea de comandos desde una interfaz web agradable.
Llamar a ./script/runner en el fondo funcionó mejor para mí. (También estaba haciendo generación de PDF.) Parece el denominador común más bajo, pero también es el más simple de implementar. Aquí hay un resumen de mi experiencia .
Sé que dijiste que no estabas preocupado por el lado del cliente, pero pensé que podrías encontrar esto interesante: Growl4Rails : notificaciones de estilo Growl que fueron desarrolladas para casi lo que estás haciendo a juzgar por el ejemplo que usan.
Una solución simple que no requiere Gemas o complementos adicionales sería crear una tarea de Rake personalizada para manejar la generación de PDF. Puede modelar el proceso de generación de PDF como una máquina de estado con estados como enviado , procesado y completo que se almacenan en la tabla de la base de datos del modelo. La solicitud HTTP inicial a la aplicación Rails simplemente agregaría un registro a la tabla con un estado enviado y devuelto.
Habría un trabajo de cron que ejecuta su tarea de Rake personalizada como un proceso separado de Ruby, por lo que la aplicación principal de Rails no se verá afectada. La tarea de Rake puede usar ActiveRecord para encontrar todos los modelos que tienen el estado enviado , cambiar el estado a procesamiento y luego generar los PDF asociados. Finalmente, debe establecer el estado para completar . Esto permite que sus llamadas AJAX dentro de la aplicación Rails supervisen el estado del proceso de generación de PDF.
Si coloca su tarea de Rake dentro de sus_rails_app / lib / tasks, entonces tendrá acceso a los modelos dentro de su aplicación Rails. El esqueleto de tal pdf_generator.rake se vería así:
namespace :pdfgenerator do
desc ''Generates PDFs etc.''
task :run => :environment do
# Code goes here...
end
end
Como se señala en la wiki, hay algunas desventajas de este enfoque. Utilizarás cron para crear regularmente un proceso Ruby bastante pesado y el tiempo de tus trabajos cron necesitaría una puesta a punto cuidadosa para asegurarte de que cada uno tenga tiempo suficiente para completar antes de que aparezca el siguiente. Sin embargo, el enfoque es simple y debe satisfacer sus necesidades.
He usado spawn antes y definitivamente lo recomendaría.
Increíblemente simple de configurar (que muchas otras soluciones no) y funciona bien.
Estoy usando Windows Vista 64 bit para mi máquina de desarrollo; sin embargo, mi máquina de producción es Ubuntu 8.04 LTS. ¿Debo considerar cambiar a Linux para mi máquina de desarrollo? ¿Las soluciones presentadas funcionarán en ambos?
¿Has considerado ejecutar Linux en una máquina virtual sobre Vista?
Consulte BackgrounDRb , está diseñado exactamente para el escenario que está describiendo.
Creo que ha existido por un tiempo y es bastante maduro. Puede controlar el estado de los trabajadores.
Es una buena idea desarrollar en la misma plataforma de desarrollo que su entorno de producción, especialmente cuando se trabaja con Rails. La sugerencia de ejecutar Linux en una VM es buena. Consulte Sun xVM para ver el software de virtualización de código abierto.
Yo personalmente uso el complemento active_messaging con un servidor activemq (stomp o protocolo de reposo). Esto ha sido extremadamente estable para nosotros, procesando millones de mensajes al mes.
Esto parece un hilo bastante viejo. Sin embargo, lo que tengo abajo en mi aplicación, que requería ejecutar múltiples temporizadores de cuenta regresiva para diferentes páginas, era usar Ruby Thread . El temporizador debe continuar ejecutándose incluso si la página fue cerrada por los usuarios.
Ruby hace que sea fácil escribir programas de subprocesos múltiples con la clase Thread. Los hilos Ruby son una forma ligera y eficiente de lograr el paralelismo en tu código. Espero que esto ayude a otros vagabundos que buscan alcanzar el trasfondo: paralelismo / servicios concurrentes en su aplicación. Del mismo modo, Ajax hace que sea mucho más fácil invocar una acción Rails [custom] específica cada segundo.
Recomiendo usar la gema Resque con su plug-in resque-status para sus procesos de fondo pesados.
Resque
Resque es una biblioteca Ruby respaldada por Redis para crear trabajos en segundo plano, colocándolos en varias colas y luego procesándolos.
Estado de Resque
resque-status es una extensión del sistema de cola de resque proporciona trabajos simples rastreables.
Una vez que ejecute un trabajo en un trabajador de Resque utilizando la extensión resque-status, podrá obtener información sobre sus progresos en curso y la capacidad de matar un proceso específico muy fácilmente. Ver ejemplos:
status.pct_complete #=> 0
status.status #=> ''queued''
status.queued? #=> true
status.working? #=> false
status.time #=> Time object
status.message #=> "Created at ..."
También resque-y resque-status tiene una interfaz web genial para interactuar con sus trabajos, que es genial.
El complemento de Workling le permite programar tareas en segundo plano en una cola (realizarían la tarea larga). A partir de la versión 0.3, puede preguntarle a un trabajador cuál es su estado, esto le permitiría mostrar algunas barras de progreso ingeniosas.
Otra característica interesante de Workling es que el back-end asíncrono se puede cambiar: puedes usar DelayedJobs, Spawn (fork clásico), Starling ...