简体   繁体   English

Ruby on Rails Sidekiq的工人执行顺序

[英]Ruby on Rails Sidekiq order of workers execution

I have rails app with Sidekiq background workers 我有与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) 

How to make MyWorker2 to be executed only if all MyWorker1 finished work? 如何使MyWorker2仅在所有MyWorker1完成工作后才能执行?

you can use GUSh 你可以使用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

and for debugging purpose you can visualize 出于调试目的,您可以可视化

bundle exec gush viz SampleWorkflow

then simple steps 然后简单的步骤

flow = SampleWorkflow.new
flow.save 

Then start worker 然后开始工作

bundle exec gush workers

Then start workflow 然后开始工作流程

flow.start!

Either you pay for it and use Sidekiq pro with 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}"

Or you just save completion status at the end of each job, and enqueue MyWorker2 if every MyWorker1 is finished: 或者,您只需在每个作业的末尾保存完成状态,然后在每个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

Maybe you can persist the result of your Worker1 result and check at the end if your result is complete. 也许您可以保留Worker1结果的结果,并在最后检查结果是否完整。 Than start worker2 from your worker1 if you have a complete result? 如果您有一个完整的结果,那么是否比从worker1启动worker2?

MyWorker1.perform_async(param_1) -> {done: false}, MyWorker1.perform_async(param_1)-> {done:false},

MyWorker1.perform_async(param_2) -> {done: false}, MyWorker1.perform_async(param_2)-> {done:false},

MyWorker1.perform_async(param_3) -> {done: false}, MyWorker1.perform_async(param_3)-> {done:false},

MyWorker1.perform_async(param_4) -> {done: true}, MyWorker1.perform_async(param_4)-> {done:true},

MyWorker1 -> if result.done? MyWorker1->如果结果完成? MyWorker2 MyWorker2

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM