什么可能导致计划的Rails活动作业消失?

Sim*_*mmo 8 ruby-on-rails delayed-job rails-activejob

我怀疑一些我们的积极工作正在消失,但我不知道为什么.下面是我发现它消失的证据,但不是原因.

我们的网站使用外部云打印服务.我们解雇工作,然后检查他们的状态.成功创建远程云打印后,我们会创建一个活动作业来立即检查状态.如果它已完成(成功或其他),则标记为如此.如果没有,那么检查状态作业会创建另一个,稍有延迟.每次延迟都会增加.

今天一个状态检查,日志显示等待达到128秒.但是没有发生下一次状态检查,并且日志中也没有错误.

我们使用延迟工作支持的积极工作.状态检查作业的代码如下.它无法在逻辑中看到任何不会导致正确收集状态检查或另一次等待尝试的缺陷.

class CheckCloudPrintStatusJob < ApplicationJob
  queue_as :default

  def perform(cloud_print, count = 0)
    cloud_print.update_status

    unless cloud_print.finished?
      count += 1
      wait = 2**(count-1)

      if count > 15
        cloud_print.mark_as_failed

        puts "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
        puts "~~~~~~~~~~~~~~~~~~ Cloud printing ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
        puts "Cloud print ##{cloud_print.id} failed"
        puts "Finally waited #{wait} seconds and then cancelled."
        puts "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
      else
        puts "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
        puts "~~~~~~~~~~~~~~~~~~ Cloud printing ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
        puts "Checking status of cloud print ##{cloud_print.id}"
        puts "Waiting #{wait} seconds and then retrying."
        puts "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"

        CheckCloudPrintStatusJob.set(wait: wait.seconds).perform_later(cloud_print, count)
      end
    end
  end
end
Run Code Online (Sandbox Code Playgroud)

wjo*_*dan 3

正确,所述逻辑中不存在会导致正确收集状态检查或再次尝试等待的缺陷。

我已通过以下设置验证您的作业代码在 128 秒等待后仍能成功运行:

  • rails new项目
  • delayed_job_active_record添加到Gemfile(正在运行bundle install
  • rails generate delayed_job:active_recordrake db:migrate安装 gems 并创建延迟作业数据库表
  • config.active_job.queue_adapter = :delayed_jobconfig/application.rb
  • 的基本CloudPrint < ApplicationRecord模型 和update_statusfinished?mark_as_failed方法app/models/cloud_print.rb
  • 中提供的代码app/jobs/check_cloud_print_status_job.rb
  • CheckCloudPrintStatusJob.perform_later(CloudPrint.create)通过 Rails 控制台运行将作业加入队列( bin/rails c)

由于上述序列表现正确,没有任何问题,因此您需要通过提供实际重现问题的更完整且可验证的示例来扩展搜索。在能够一致地重现问题后,将整个 Rails 项目上传到 GitHub 存储库,或者调查环境和项目配置的其他方面。以下是一些可能性:

  • 您的模型类中可能存在可能引发任何异常的逻辑;
  • 工作处理守护进程可能已被中止或终止;
  • 作业队列可能已被清除(例如,通过rake jobs:clear
  • 另一个进程可能已经修改和/或删除了正在处理的模型对象;
  • finished?可能在调用true后返回update_status,导致即使处理成功完成,也无法打印最终状态检查。

注意 - 延迟作业支持重试失败的作业,延迟为5 seconds + N ** 4,其中N是尝试次数,无需自己重新实现此逻辑。如果为 false,则只是raise一个例外cloud_print.finished?,您不需要任何其他自定义延迟代码:

class CheckCloudPrintStatusJob < ApplicationJob
  queue_as :default

  def perform(cloud_print)
    raise 'Not ready' unless cloud_print.finished?
  end
end
Run Code Online (Sandbox Code Playgroud)