如何确保一个 sidekiq 工作线程在 Ruby on Rails 中的另一个工作线程完成后运行

问题描述 投票:0回答:1

我正在开发一个 Ruby on Rails 应用程序,该应用程序利用 Sidekiq(版本 6.5.8)进行后台作业处理。在我的应用程序中,我有一个特定的要求:我需要确保第二个 Sidekiq 工作程序仅在第一个 Sidekiq 工作程序成功完成其任务后才开始执行。

为了提供更多上下文,我的应用程序中有一个启动第一个工作线程的服务。该工作人员负责更新某些客户信息。此外,还有第二个工作人员旨在向用户发送电子邮件,表明更新过程已完成。我的目标是建立一个顺序工作流程,一旦第一个工作人员完成其工作,就会自动调用第二个工作人员。

需要注意的是,我的应用程序的运行配置涉及多个工作线程的并发执行。鉴于此设置,在服务中使用 Perform_async 调用两个工作线程并不是一个可行的解决方案,因为它可能无法保证所需的执行顺序。

此外,相关更新服务是由用户通过应用程序端点之一调用的。因此,它是用户触发的,需要一种机制来确保第二个工作人员仅在第一个工作人员成功完成其任务后才执行。

考虑到 Sidekiq 的并发特性和更新服务的用户触发特性,如何在 Rails 应用程序中实现 Sidekiq 工作线程的有序执行?

我尝试实现回调函数“after_perform”,但它似乎与我当前的 Sidekiq 版本(6.5.8)不兼容。此外,如果可能的话,我不想将这两个工作人员紧密结合在一起。

ruby-on-rails jobs sidekiq worker
1个回答
0
投票

实现此目的最直接的方法是简单地在第一个作业中调用第二个作业:

class UpdateCustomerInfoJob
  include Sidekiq::Job

  def perform(data)
    # Some logic to update the customer info

    # Once it reaches this point, it means
    # the job completed successfully and will
    # execute the second job.
    EmailCustomerJob.perform_async(
      email: data[:email]
    )
  end
end

据我所知,没有其他模式/配置可以纯粹在 Sidekiq 中完成来顺序执行作业。这也是基于 Sidekiq 的 FAQ:

Sidekiq 专为异步处理作业而设计,这些作业可以隔离且彼此独立地完成。

如果你真的愿意,你可以尝试集成第三方 gem,如 sidekiq-sequence:

# sequence class
class UpdateCustomerSequence < Sidekiq::Sequence::Base
  step UpdateCustomerInfoJob
  step EmailCustomerJob
end

# execute sequence
UpdateCustomerSequence.new(
  email: 'som[email protected]',
  first_name: 'John',
  last_name: 'Doe'
)

但是,您需要考虑这些好处是否值得额外的依赖。另外,只是一个警告:宝石没有得到积极维护。

© www.soinside.com 2019 - 2024. All rights reserved.