我有一个从其他网站提取数据的功能,最多需要30秒才能完成。我需要这个函数来执行来自用户的Web请求,但不希望他等待那个时间。
目前,该方法是从我的视图控制器中调用的。
如何让该方法在他自己的时间执行而不是让用户等待?
答案 0 :(得分:1)
您需要有一个处理这些请求的后台代理。我最近使用beaneater gem和beanstalkd为消息队列实现了类似的东西。我使用God Gem来管理后台进程,并编写了一个init脚本来管理上帝进程。页面中的JavaScript每1.5秒进行一次AJAX调用,以查询请求的状态并告知用户何时完成。
我随后得知上帝已知有内存泄漏,因此Bluepill可能是更好的选择。就在今天,我还发现http://michaelvanrooijen.com/articles/2011/06/08-managing-and-monitoring-your-ruby-application-with-foreman-and-upstart/描述了使用Foreman和Upstart进行后台处理,这似乎是一种更直接,更健壮的方法。下次我需要做这种事情时,我可能会尝试Foreman / Upstart / beaneater / beanstalkd。
请注意,有许多不同的消息队列可供选择,具有不同的优点和缺点。 beanstalkd非常敏感,这对于运行需要几分钟或更短时间的进程非常有用。
答案 1 :(得分:1)
如果您要向用户显示的响应不依赖于长进程的结果,那么您需要做的就是在与主请求不同的线程中执行该进程。
你当然可以采用史蒂夫的方法并使用处理队列(delayed_job,sidekiq,resque),但这听起来有点矫枉过正。您可以简单地分叉一个新的subprocess并将其分离或分叉一个新的thread
pid = Process.fork do
long_process
end
Process.detach pid