当工作完成时,Sidekiq应该如何在网页上通知用户?

时间:2017-06-22 02:13:45

标签: ruby-on-rails ruby sidekiq

用户可以通过由控制器操作处理的Web界面在我的系统中上传多个文件。

  def import
    paths = params[:files].map(&:path) if params[:files].present?
    if paths
      @results = MyRecord.create_from paths
    end 
    redirect_to confirmation_my_records_path
  end

class MyRecord < ActiveRecord::Base
  def self.create_from(paths)
    paths.each do |path|
      MyRecordWorker.perform path 
    end    
  end
end


works/my_record_worker.rb
class MyRecordWorker
  include Sidekiq::Worker
  def perform(path)
      # each time this is run, it is no I/O, just expensive math calculations that take minutes
      collection = ExpensiveOperation.new(path).run 
      if collection && collection.any?
        save_records(collection)
      else
        []
      end
  end
end

由于sidekiq作业将在后台运行,如何通过确认页面通知用户作业已完成?我们不知道作业何时完成,因此Rails请求和响应周期在加载确认页面时无法确定任何内容。如果确认页面只是说&#34;处理...&#34;然后让Faye在作业完成后更新页面?

2 个答案:

答案 0 :(得分:3)

只需在您的应用程序中添加RecordJobs模型,该模型可存储上传记录的人员,记录数量,上传时间等。

每当有人上传新记录并将其record_job传递给工作人员时,请创建新的id。工作人员可以更新该实例以指示其进度。

同时,应用程序可以查询现有的record_job并显示其进度。只要用户重新加载页面,通过活动轮询或使用Web套接字(根据您的需要),就可以完成此操作。

答案 1 :(得分:1)

使用ActionCable,这是报告频道的示例

在routes.rb中添加以下行

mount ActionCable.server => '/cable'

使用以下代码

在app / channels中创建ReportChannel.rb
class ReportChannel < ApplicationCable::Channel
  def subscribed 
    stream_from "report_#{current_user.id}"
  end
end

使用以下代码在app / assets / javascripts / channels中创建reports.coffee

  window.App.Channels ||= {}
  window.App.Channels.Report ||= {}
  window.App.Channels.Report.subscribe = ->
      App.report = App.cable.subscriptions.create "ReportChannel",
        connected: ->
          console.log('connected ')

        disconnected: ->
          console.log('diconnected ')

        received: (data) ->
          console.log('returned ')
          data = $.parseJSON(data)
          #write your code here to update or notify user#

并在作业结束时添加以下行

ActionCable.server.broadcast("*report_*#{current_user_id}", data_in_json_format) 

用您的特定型号替换报告

似乎很简单:)