完成工作后如何更新部分

时间:2011-04-16 00:58:28

标签: ruby-on-rails

这是我在这里的第一篇文章,但我已经从这个网站获得了一些很好的信息。所以我觉得有人可能会帮忙。

在我看来,我有一个表单,一旦提交,控制器将作业传递给navvy,它确实运作良好。问题是,一旦navvy完成工作,我想在同一页面上使用新信息进行表单更新。所以在我的控制器中我有:

Navvy::Job.enqueue( GetZip, :get_zip,  @series, :job_options => {:priority => 8})

然后在我的navvy块中,它位于config / initializers / navvy.rb中我有:

class GetZip
def self.get_zip(params)
  fetch = Fetch.new
  fetch.get_zip(params)
# What to put here to update partial #
end
end

哪个按预期工作。我只是不确定在我的视图中如何在漫游工作完成后更新部分。任何建议都将不胜感激。

2 个答案:

答案 0 :(得分:4)

这里的问题是,一旦你启动了一个后台进程,你就不再需要与该用户的请求相关联(这显然是后台进程的重点)。

因此,您的后台工作不知道用户在此期间正在做什么。例如,他们可以导航到另一个页面,甚至可以离开您的网站。

您可以获得后台作业,在数据库中创建一条记录,表明它已经开始处理并在完成处理后更新此状态。这样,当用户下次刷新页面时,您可以检查该记录的状态,并且可以相应地更新部分。

如果您希望页面自动更新,您可以使用ajax请求继续轮询该记录的状态。在最初提交表单时,您可以开始轮询而不是一直运行。

答案 1 :(得分:0)

这是我正在使用的。 这就是约伯所在的地方:

Setting::progress = "Starting..."
Navvy::Job.enqueue(EmailWorker, :async_email, stuff)

设置非常简单:

class Setting < ActiveRecord::Base
  def Setting::progress=(value)
    setn = Setting.find_or_initialize_by_name("email_status")
    setn.value = value
    setn.save
  end
end

和挖掘工作EmailWorker是:

class EmailWorker
  def self.async_email(options)
    # send one at a time
    total = options[:list].length
    errors = []
    options[:list].each_with_index do |email_addr, n|
      begin
        Setting::progress = "#{n+1}/#{total}: #{email_addr}"
        Postoffice.one_notice(email_addr, options).deliver
      rescue Exception => e
        Setting::progress = "#{email_addr} #{e.message}"
        errors << "<span class='red'>#{email_addr}</span> #{e.message}"
      end     
      # get stack level too deep errors at random when this is removed. I don't get it.
      sleep 0.05 
    end
    Setting::progress = "DONE sending #{total} with #{errors.length} errors<br/>#{errors.join("<br/>")}"
    "Done"  # just for display in Navvy console output
  end
end

然后触发页面有:

<%- 
# had to add this back as rails 3 took it away
  def periodically_call_remote(options = {})
    frequency = options[:frequency] || 10 # every ten seconds by default
    code = "new PeriodicalExecuter(function() {#{remote_function(options)}}, #{frequency})"
    javascript_tag(code)
  end
-%>
<script type="text/javascript">
//<![CDATA[
  check_var = true;
//]]>
</script>
<%= periodically_call_remote(
      :condition => "check_var == true",
      :url => { :controller => "application", 
      :action => "update" }, 
      :frequency => '3') -%>
<div id="progress">
  <p>Monitoring progress of emails</p>
</div>

继承了重复调用的方法:

def update
  raise "not for direct" if (!request.xhr?)
  @progress = Setting::progress
  @again = !(/^DONE/ =~ @progress)
  render :action => "update"
end

通过update.rjs

进行就地更新
page.assign('check_var', @again)
page.replace_html "progress", :partial => "info", :locals => { :info => @progress } 
page.visual_effect :highlight, 'progress', :startcolor => "#3333ff",  :restorecolor => '#ffffff', :duration => 0.5

关于Navvy的一个警告 - 由于它在被杀之前作为后台任务运行,因此当你进行上限时,它将继续执行你的旧应用程序。你必须在旧的“当前”中杀死挖掘机并转移到新的“当前”。