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

时间:2017-02-02 16:05:23

标签: 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

2 个答案:

答案 0 :(得分:4)

正确,所述逻辑中没有任何缺陷会导致正确收集状态检查或另一次等待尝试。

我已经通过以下设置验证了您的工作代码在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_job
  • config/application.rb
  • CloudPrint < ApplicationRecord
  • 中包含update_statusfinished?mark_as_failed方法的基本app/models/cloud_print.rb模型
  • app/jobs/check_cloud_print_status_job.rb
  • 中提供的代码
  • 通过Rails控制台CheckCloudPrintStatusJob.perform_later(CloudPrint.create)运行bin/rails c来排队作业

由于上述序列运行正常且没有任何问题,因此您需要通过提供实际重现问题的更多complete and verifiable example来扩展搜索范围。一旦您能够一致地重现问题,或者调查环境和项目配置的其他方面,就可以将整个Rails项目上传到GitHub仓库中。以下是一些可能性:

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

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

class CheckCloudPrintStatusJob < ApplicationJob
  queue_as :default

  def perform(cloud_print)
    raise 'Not ready' unless cloud_print.finished?
  end
end

答案 1 :(得分:0)

从作业代码中可以看出,参数public partial class Window1 : Window { public Window1() { InitializeComponent(); textBox1.DataContext = this; } public int SomeProperty { get; set; } } 是某个Ruby类的实例(似乎是ActiveRecord :: Base)。将复杂对象作为后台作业的参数通常不是一个好主意,因为这些参数必须序列化为string,json或yaml。 DelayedJob使用YAML序列化对象,有时可能无法恢复模型实例。例如,如果延迟作业作为回调cloud_print运行 - 模型对象尚未保存,则无法恢复。可在此处找到更多信息https://github.com/collectiveidea/delayed_job/wiki/Common-problems#jobs-are-silently-removed-from-the-database