【问题标题】:Sidekiq job error handling and retries inside parent job?Sidekiq 作业错误处理并在父作业中重试?
【发布时间】:2020-06-23 00:56:03
【问题描述】:

我有一个工作,它会产生其他工作并且内联做一些事情。

abc_job.rb

class AbcJob
  def perform
    post_events
  end

  private

  def post_events
    foo
    bar
    done
  end

  def foo
    OneJob.perform_later({})
  end

  def bar
    TwoJob.perform_later({})
  end

  def done
    ThreeJob.perform_later({})
  end
end

需要处理错误并为abc_job 内的所有作业添加重试。

一种方法是在 post_events 内为所有方法添加 begin rescue。

请建议最好的方法,并且还需要为子作业添加重试。

【问题讨论】:

    标签: ruby-on-rails ruby jobs sidekiq


    【解决方案1】:

    您可以做的一种方法是使用元编程。您可以创建一个外部模块,例如 ExceptionHandler -> 您可以在此处 rescue 您的错误以及处理错误时的操作 -> 然后将此模块包含在您的 AbcJob 文件中。

    例如:

    1. 创建模块文件:

      module ExceptionHandler
        extend ActiveSupport::Concern
      
        # Define custom error subclasses - rescue catches `StandardErrors`
        class InvalidToken < StandardError; end
        class MissingToken < StandardError; end
      
        included do
          # Define in-built handlers
          rescue_from ActiveRecord::RecordNotFound, with: :four_not_four
          rescue_from ActiveRecord::RecordInvalid, with: :four_not_four
      
          # Define custom handlers
          rescue_from ExceptionHandler::MissingToken, with: :unauthorized_request
          rescue_from ExceptionHandler::InvalidToken, with: :unauthorized_request
        end
      
        private
          ## Action on what to do when error occurs
          def four_not_four
            redirect_to root_path, alert: "This page was not found"
          end
      
          def unauthorized_request
            redirect_to root_path, alert: "You're not authorized to perform this request"
          end
      end
      
    2. 然后在你的Abcjob 文件中,只包含这个模块:

      class AbcJob
        include ExceptionHandler
      
        def perform
          post_events
        end
      
        ...
      end
      
    3. 现在,每当作业抛出处理程序时,都会触发您在ExceptionHandler 中提到的方法并运行它们。

    【讨论】:

      【解决方案2】:

      没有一种简单的方法可以实现使用 Sidekiq 处理父级内部子作业中的错误的目标。他们问题的关键是AbcJob 只是为孩子们制定了时间表,然后就完成了。即使在另一台服务器上,子作业也可以在技术上执行,并且所有异常都在那里发生。通常,在子进程正在处理的时候,父作业已经完成,因此没有可以处理异常的上下文(进程)。使用 Sidekiq 是处理子作业内部异常并从那里执行一些补偿操作的唯一方法。错误处理可能包括重新启动或其他逻辑(包括直接执行父作业)。 可能是一个最简单的解决方案 - 不要异步运行子作业,只需在同一个父作业中执行它们。这可能不是所要求的,但可以作为一种选择。

      附带说明 - 您可能会查看 Elixir/Erlang,其中将所需的行为包含在语言设计中:

      Elixir(Erlang) 有一个很好的工具来生成子进程并监控它们的状态:父进程可以轻松地等待所有子进程完成并处理它们的结果,包括异常。 http://blog.plataformatec.com.br/2018/04/elixir-processes-and-this-thing-called-otp/

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-08-07
        • 2015-05-27
        • 2014-01-14
        • 2015-07-06
        • 2018-09-27
        • 2015-07-03
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多