2

我有一个从其他网站提取数据的功能,最多需要 30 秒才能完成。我需要这个函数来执行来自用户的网络请求,但不希望他等待那个时间。

目前该方法是从我的视图控制器中调用的。

我怎样才能让该方法在他自己的时间执行而不是让用户等待?

4

2 回答 2

1

您需要有一个处理这些请求的后台代理。我最近使用 beaneater gem 和 beanstalkd 为消息队列实现了类似的东西。我使用God Gem 来管理那个后台进程,并编写了一个init 脚本来管理God 进程。页面中的 JavaScript 每 1.5 秒进行一次 AJAX 调用,以查询请求的状态并在完成时告诉用户。

后来我了解到,众所周知,God 有内存泄漏,所以 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 响应速度非常快,非常适合运行需要几分钟或更短时间的进程。

于 2013-02-15T09:18:07.360 回答
1

如果您要向用户显示的响应不取决于您的长流程的结果,那么您需要做的就是在与主请求不同的线程中执行该流程。

您当然可以采用 Steve 的方法并使用处理队列(delayed_job、sidekiq、resque),但这听起来有点矫枉过正。您可以简单地分叉一个新的进程并将其分离或分叉一个新线程

pid = Process.fork do 
  long_process
end
Process.detach pid
于 2013-02-18T12:46:15.113 回答