2010-07-07 66 views
1

进度条与线程我有时间采取任务在我的控制器,我要触发我认为一个简单的进度条/进度状态。更改视图 - Rails中

在我的控制器我有类似

threads = [] 
total.times do |x| 
    Thread.new { 
     the_time_taking_task(x) 
     #Something here to trigger the progressbar in the view 
    } 
end 

threads.each { |aThread| aThread.join } 
render :action => 'some_action'  

我不能把一个呈现在那里,因为它抛出一个双重渲染错误。 我试图把渲染,并返回那里,我得到了“return can't jump across threads”错误

我试图渲染,因为它似乎是我的控制器可以跟查看的唯一途径。我的方法错了吗?

希望在通过电话

<div style="width: <%= (percent_val)%>px; "> 

请咨询应用进度条宽度认为简单的东西是这样的。

+0

任何长时间运行的任务应该作为后台进程运行(异步和非阻塞)。正如@ shingara所说,使用delayed_job或其它类似的。我发现delayed_job是迄今为止最容易实现的。检查delayed_job上的railscast。 – 2010-07-07 13:01:50

回答

6

是的,这是一种错误的做法。

网络是无状态的,你不能阻止进程渲染视图,并通过另一个请求后得到它。

的好方法是:

1)生成一个队列任务,而不是你的线程。您可以使用delayed_job的,resque或队列系统,如RabbitMQ的或beanstalkD

2)添加控制器检查,如果队列中的过程到底又是怎样的进步。在里面,你把队列ID和检查是否结束并返回进度百分比。

最简单的方法是做到这一点的阿贾克斯。

2

是的,你的方法是错误的。

shingara很好地解释了这一点。

我提供给你一个稍微具体的解决方案。

为了得到你想要的效果,你基本上需要以下步骤:

  1. 卸载线程进入一个后台作业服务器。结账resquedelayed_job
  2. 让后台工作将进度写入数据库或某些持久性介质。
  3. 在Rails中,编写返回当前进度(如JSON或XML)
  4. 在视图的动作,编写调用写入在步骤3
  5. 更新的视图相应的动作周期Ajax请求。

你完成了! :D