work tutorial rails job delayed active ruby-on-rails ruby background-process

tutorial - Ruby on Rails: ¿Cómo ejecutar cosas en segundo plano?



rails job work (7)

Cuando se crea un nuevo recurso y necesita realizar un procesamiento prolongado antes de que el recurso esté listo, ¿cómo puedo enviar ese procesamiento a un segundo plano donde no retendrá la solicitud actual u otro tráfico a mi aplicación web?

en mi modelo:

class User < ActiveRecord::Base after_save :background_check protected def background_check # check through a list of 10000000000001 mil different # databases that takes approx one hour :) if( check_for_record_in_www( self.username ) ) # code that is run after the 1 hour process is finished. user.update_attribute( :has_record ) end end end


¡Acabo de experimentar con la gema ''delayed_job'' porque funciona con la plataforma de hospedaje Heroku y fue ridículamente fácil de configurar!

Agregue gema a Gemfile, bundle install , rails g delayed_job , rake db:migrate rails g delayed_job Luego inicie un controlador de cola con;

RAILS_ENV=production script/delayed_job start

Donde tiene un método de llamada que es su proceso largo es decir

company.send_mail_to_all_users

lo cambias a

company.delay.send_mail_to_all_users

Compruebe la documentación completa en github: delayed_job


Comience un proceso separado, que probablemente se hace más fácilmente con el system , anteponiendo un ''nohup'' y agregando un ''&'' al final del comando que lo pasa. (Asegúrese de que el comando sea solo un argumento de cadena, no una lista de argumentos).

Hay varias razones por las que desea hacerlo de esta manera, en lugar de, digamos, tratar de usar subprocesos:

  1. Los hilos de Ruby pueden ser un poco complicados cuando se trata de hacer E / S; Tienes que tener cuidado de que algunas cosas que haces no bloqueen todo el proceso.

  2. Si ejecuta un programa con un nombre diferente, es fácilmente identificable en ''ps'', por lo que no cree accidentalmente que sea un back-end FastCGI que se haya vuelto loco o algo así, y lo mate.

En realidad, el proceso que inicie debe estar "desmitificado", consulte la clase Daemonize para obtener ayuda.


Creo que spawn es una excelente manera de dividir tu proceso, hacer un procesamiento en segundo plano y mostrarle al usuario solo una confirmación de que se inició este procesamiento.



Me gusta usar backgroundrb, es bueno que te permite comunicarte durante largos procesos. Para que pueda tener actualizaciones de estado en su aplicación Rails


Qué pasa:

def background_check exec("script/runner check_for_record_in_www.rb #{self.username}") if fork == nil end

El programa " check_for_record_in_www.rb " se ejecutará en otro proceso y tendrá acceso a ActiveRecord, pudiendo acceder a la base de datos.


lo ideal es utilizar un servidor de trabajo en segundo plano existente, en lugar de escribir el suyo propio. estos normalmente te permitirán enviar un trabajo y darle una clave única; luego puede usar la tecla para consultar periódicamente el estado de su trabajo a jobserver sin bloquear su aplicación web. Aquí hay un buen resumen de las diversas opciones que hay.