达到最大尝试次数后如何处理失败的 Rails ActiveJob?

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

我正在寻找一种方法来处理达到最大重试尝试次数的 Rails ActiveJob 作业。

这是我的代码片段:

class UserJob < ApplicationJob
  queue_as :default
  retry_on StandardError, wait: :polynomially_longer, attempts: 3

  def perform(user)
    # Do things here
  end
end

就我而言,该工作会尝试一些事情,包括连接到第 3 方 API。碰巧API有几次不可用并且达到了最大尝试次数。

在这种情况下,我想捕获这种情况并执行一些额外的逻辑,例如更新用户记录并通知我们的团队。

我正在使用 SolidQueue,并且正在考虑获取

executions
计数参数,但同样,我需要确定作业肯定失败的时刻。

有什么可靠的解决方案吗?看来我正在寻找死信队列系统。

谢谢

ruby-on-rails rails-activejob solid-queue
1个回答
0
投票

这些只是我集思广益的解决方案,我认为有两种选择可以解决这个问题:

注意:避免将整个对象传递到队列,只传递 id 并将对象加载到作业中

  1. 自行重试

a.如果由于 API 可用而失败,请考虑该标志始终为 true 以供稍后重试

class UserJob < ApplicationJob
  MAX_RETRY = 3

  def perform(user_id, api_available: true, current_retry: 0)
    # Your job logic here

    # If API failed once, api_available flag will always false, depend on your demand, you can change this logic
  rescue FailedByAPINotAvailableError
    additional_action if current_retry == MAX_RETRY

    self.class.perform_later(user_id, api_available: false, current_retry: current_retry.next) if current_retry < MAX_RETRY
  rescue StandardError
    self.class.perform_later(user_id, api_available: api_available, current_retry: current_retry.next) if current_retry < MAX_RETRY
  end

  def additional_action
  end
end

b.仅检查 MAX_RETRY 的最后一次重试 api 是否失败

class UserJob < ApplicationJob
  MAX_RETRY = 3

  def perform(user_id, current_retry: 0)
    # Your job logic here
  rescue FailedByAPINotAvailableError
    additional_action if current_retry == MAX_RETRY

    self.class.perform_later(user_id, current_retry: current_retry.next) if current_retry < MAX_RETRY
  rescue StandardError
    self.class.perform_later(user_id, current_retry: current_retry.next) if current_retry < MAX_RETRY
  end

  def additional_action
  end
end
  1. 创建一个表来存储job_data,每个作业通常在数据库中都会有一条记录,该表将有2列:id和data(使用序列化器从yml或json解析数据)。然后将 job_data_id 传递给作业以跟踪作业的最新状态并进行相应更新
© www.soinside.com 2019 - 2024. All rights reserved.