0

早上好!

我有一个表单,其中包含 IP、开始日期和停止日期,它调用 SideKiq 工作人员,该工作人员通过 ssh 在外部服务器上执行脚本,然后将生成的文件通过 sFTP 发送到本地服务器。

控制器方法:

def create
  @script = Script.new(params[:script])
  if @script.valid?
    @job_id = LogsWorker.perform_async(@script.ip, @script.start_date, @script.stop_date)
  else
    render :action => 'new'
  end
end

SideKiq 工人:

def perform(ip, start_date, stop_date)
  Net::SSH.start('server', 'username') do |ssh|
    result = ssh.exec!("<script here> #{ip} #{start_date} #{stop_date}")
    ssh.sftp.connect do |sftp|
      local_result = "#{Rails.root}/public/uploads/" + File.basename(result)
      sftp.download!(result, local_result)
    end
  end
    .. to be continued ..

我还让 SideKiq 工作人员将生成的文件解析为哈希:

  .. continuing ..
  @file_hash = {}
  i = 0
  File.open(local_result, "r") do |fp|
    fp.each_line do |line|
      ip, date, method, url_full = line.split("\t")
      @file_hash[i] = {ip: ip, date: date, method: method, url_full: url_full}
      i += 1
    end
  end
end

以及解析它的部分_results.html.erb

<% if @file_hash %>
  <% @file_hash.each do |key, value| %>
    <tr>
      <td><%= value[:ip] %></td>
      <td><%= value[:date] %></td>
      <td><%= value[:method] %></td>
      <td><%= value[:url_full] %></td>
    </tr>
  <% end %>
<% end %>

我尝试在 create.js.coffee 文件中完成作业后渲染结果<%= render partial: 'results', locals: { file_hash: @file_hash } %>,但我认为它对实例变量没有任何想法。

如何将完成的 SideKiq 变量的结果传递给视图?我想我应该注意我有另一个控制器方法可以查询 SideKiq 作业的完成百分比,所以我应该能够知道它何时完成。

编辑:

percentage_done在控制器中

def percentage_done
  job_id = params[:job_id] # grabbing the job_id from params

  container = SidekiqStatus::Container.load(job_id)

  @pct_complete = container.pct_complete

  respond_to do |format|
    format.json {
      render :json => {
        :percentage_done => @pct_complete, # responding with json with the percent complete data
      }
    }
  end
end

当前的ajax

queryForPercentage = () ->
  job_id = $('#job_id').text() # grabbing the job_id
  $.ajax({
    url: "/percentage_done" # sending an ajax request to /percentage_done
    data: job_id: job_id # using the job_id from the DOM
    success: (data) -> # executed after a successful call to the percentage_done controller
      percentage = 'width: ' + data['percentage_done'] + '%;'
      # writing the percentage done to the progress bar
      $('#job-progress').attr('style', percentage).text(data['percentage_done'] + '%')
      $('#job-progress').attr('aria-valuenow', data['percentage_done'])

      if $('#job-progress').text() != '100%'
        setTimeout((-> queryForPercentage()), 1500)
      else
        # replace the html of the div script_lists with the updated new one
        $("#scripts_list").html("<%= escape_javascript(render partial: 'results', locals: { file_hash: @file_hash } ) %>");
  })

queryForPercentage()
4

1 回答 1

1

Sidekiq 用于处理后台作业。IMO 将 Sidekiq 作业的结果发送回视图违背了使用 Sidekiq 的目的;为什么不在同一个请求中执行这项工作。

话虽如此,您可以通过对视图进行 AJAX 调用来完成此操作,该视图轮询查询 Sidekiq 以完成的控制器。该控制器还可以返回文件的内容。如果 Sidekiq 工作不需要太长时间即可完成,那么用户体验可能不会很差。

于 2014-06-27T15:55:32.073 回答