Ruby on Rails Sidekiq工人执行顺序

时间:2015-08-07 08:31:27

标签: ruby-on-rails ruby sidekiq

我有Sidekiq后台工作人员的rails应用程序

MyWorker1.perform_async(param_1)
MyWorker1.perform_async(param_2) 
MyWorker1.perform_async(param_3)
MyWorker1.perform_async(param_4)

MyWorker2.perform_async(param_5) 

如果只有在所有MyWorker1完成工作后才能执行MyWorker2?

3 个答案:

答案 0 :(得分:2)

您可以使用GUSh

class SimpleworkFlow < Gush::Workflow
   run MyWorker1, params: {param_1}
   run Myworker1, params: {param_2}
   run MyWorker1, params: {param_3}
   run MyWorker1, params: {param_4}
   run Myworker2, params: {param_5}, after: MyWorker1
end

并且出于调试目的,您可以可视化

bundle exec gush viz SampleWorkflow

然后简单的步骤

flow = SampleWorkflow.new
flow.save 

然后启动工作人员

bundle exec gush workers

然后启动工作流程

flow.start!

答案 1 :(得分:1)

要么支付费用,请使用带有Batches的Sidekiq专业版:

class CallNextJob
  def on_success(status, options)
    MyWorker2.perform_async(options[:bundle])
  end
end

params = [param1, param2, param3, param4]
batch = Sidekiq::Batch.new
batch.on(:success, CallNextJob, bundle: param5)
batch.jobs do
  params.each {|param| MyWorker1.perform_async(param)}
end
puts "Just started Batch #{batch.bid}"

或者您只是在每个作业结束时保存完成状态,并在每个MyWorker1完成时将MyWorker2排队:

# Worker1
def heavy_load(job_id)
  # do the load
  ...
  # save state
  WorkerReport.create(worker_id: job_id)
end

class WorkerReport < ActiveRecord::Base
  after_commit :do_next

  private

  # It's important to do that in after_commit block to evade strange bugs
  # When you create next job here, you are absolutely sure that
  # current WorkerReport is already saved to base
  def do_next
    # Check if other Worker1 jobs from current bundle are finished
    if self.where(...).exists?
      Worker2.perform_async(...)
    end
  end
end

答案 2 :(得分:1)

也许您可以保留Worker1结果的结果,并在结果处检查结果是否完整。如果您有完整的结果,请从您的worker1启动worker2?

MyWorker1.perform_async(param_1) - &gt; {done:false},

MyWorker1.perform_async(param_2) - &gt; {done:false},

MyWorker1.perform_async(param_3) - &gt; {done:false},

MyWorker1.perform_async(param_4) - &gt; {done:true},

MyWorker1 - &gt;如果result.done? MyWorker2