我怀疑我们的一些活跃工作正在消失,但我不知道为什么。下面是我发现它消失的证据,但不是原因。
我们的网站使用外部云打印服务。我们解雇工作,然后检查他们的状态。成功创建远程云打印后,我们会创建一个活动作业来立即检查状态。如果它已完成(成功或其他),则标记为如此。如果没有,那么检查状态作业会创建另一个,稍有延迟。延迟每次都会增加。
今天进行状态检查,日志显示等待时间达到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
答案 0 :(得分:4)
正确,所述逻辑中没有任何缺陷会导致正确收集状态检查或另一次等待尝试。
我已经通过以下设置验证了您的工作代码在128秒等待后成功运行:
rails new
项目delayed_job_active_record
已添加到Gemfile
(正在运行bundle install
)rails generate delayed_job:active_record
和rake db:migrate
安装gems并创建延迟作业数据库表config.active_job.queue_adapter = :delayed_job
中config/application.rb
CloudPrint < ApplicationRecord
update_status
,finished?
和mark_as_failed
方法的基本app/models/cloud_print.rb
模型
app/jobs/check_cloud_print_status_job.rb
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