Ruby 关于 Rails 工人执行的 Sidekiq 顺序
Ruby on Rails Sidekiq order of workers execution
我有 rails 带有 Sidekiq 后台工作程序的应用程序
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)
如何让MyWorker2只在MyWorker1全部工作完成后才执行?
要么你付钱然后用 Sidekiq pro 和 Batches:
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
也许你可以持久化你的Worker1的结果,最后检查你的结果是否完整。如果你有一个完整的结果,那么从你的 worker1 开始 worker2?
MyWorker1.perform_async(param_1) -> {完成: false},
MyWorker1.perform_async(param_2) -> {完成: false},
MyWorker1.perform_async(param_3) -> {完成: false},
MyWorker1.perform_async(param_4) -> {完成:真},
MyWorker1 -> 如果 result.done?我的工人 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
然后启动worker
bundle exec gush workers
然后开始工作流程
flow.start!
我有 rails 带有 Sidekiq 后台工作程序的应用程序
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)
如何让MyWorker2只在MyWorker1全部工作完成后才执行?
要么你付钱然后用 Sidekiq pro 和 Batches:
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
也许你可以持久化你的Worker1的结果,最后检查你的结果是否完整。如果你有一个完整的结果,那么从你的 worker1 开始 worker2?
MyWorker1.perform_async(param_1) -> {完成: false},
MyWorker1.perform_async(param_2) -> {完成: false},
MyWorker1.perform_async(param_3) -> {完成: false},
MyWorker1.perform_async(param_4) -> {完成:真},
MyWorker1 -> 如果 result.done?我的工人 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
然后启动worker
bundle exec gush workers
然后开始工作流程
flow.start!