Ruby on Rails:如何在后台运行东西?

创建新资源并且在资源准备好之前需要进行一些冗长的处理时 ,如何将该处理发送到后台 ,它不会阻止当前请求或其他流量到我的网络应用程序?

在我的模型中:

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 

你应该看看以下Railscasts:

他们解释了如何以各种可能的方式在Rails中运行后台进程(有或没有队列……)

启动一个单独的过程,这可能是最容易用system完成的,在“nohup”之前添加’并且在你传递它的命令的末尾附加’&’。 (确保命令只是一个字符串参数,而不是参数列表。)

您希望以这种方式执行此操作有几个原因,而不是尝试使用线程:

  1. 在执行I / O时,Ruby的线程可能有点棘手; 你必须注意你做的一些事情不会导致整个过程被阻止。

  2. 如果你运行一个具有不同名称的程序,它很容易在’ps’中识别,所以你不会意外地认为它是一个疯狂的FastCGI后端或什么东西,并杀了它。

实际上,你开始的过程应该是“deamonized”,请参阅Daemonize类获取帮助。

我刚刚尝试了’delayed_job’gem,因为它可以与Heroku托管平台一起使用,设置非常简单!

将gem添加到Gemfile, bundle installrails g delayed_jobrake db:migrate然后启动队列处理程序;

 RAILS_ENV=production script/delayed_job start 

你有一个方法调用,这是你漫长的过程,即

 company.send_mail_to_all_users 

你把它改成了;

 company.delay.send_mail_to_all_users 

查看github上的完整文档: https : //github.com/collectiveidea/delayed_job

理想情况下,您希望使用现有的后台作业服务器,而不是自己编写。 这些通常会让你提交一份工作并给它一个独特的钥匙; 然后,您可以使用该密钥定期查询作业服务器以获取作业状态,而不会阻止您的Web应用程序。 这里是各种选项的精彩综述 。

我喜欢使用backgroundrb,它很好,它允许你在长时间的过程中与它进行通信。 因此,您可以在rails应用中进行状态更新

我认为spawn是一个很好的方法来分叉你的进程,在后台进行一些处理,并向用户显示这个处理开始的一些确认。

关于什么:

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

然后,程序“ check_for_record_in_www.rb ”将在另一个进程中运行,并且可以访问ActiveRecord,从而能够访问数据库。