Ruby on rails 如何使延迟作业排队
我正在Rails中为Azure的Media Services API实现一个视频流接口,我需要不断更新上传的视频,以便通过Media Services处理(复制、编码),状态最终将为可用或失败。为了做到这一点,我决定使用延迟作业,但是,我不确定什么是保持作业始终运行的最佳方法Ruby on rails 如何使延迟作业排队,ruby-on-rails,ruby,delayed-job,Ruby On Rails,Ruby,Delayed Job,我正在Rails中为Azure的Media Services API实现一个视频流接口,我需要不断更新上传的视频,以便通过Media Services处理(复制、编码),状态最终将为可用或失败。为了做到这一点,我决定使用延迟作业,但是,我不确定什么是保持作业始终运行的最佳方法 class UpdateAzureVideosJob < ApplicationJob queue_as :azure_media_service def perform to_update = A
class UpdateAzureVideosJob < ApplicationJob
queue_as :azure_media_service
def perform
to_update = AzureVideo.all.map{ |v| v if v.state != 5 }.compact
unless to_update.empty?
to_update.each do |video|
video.update
end
end
sleep(5)
Delayed::Job.enqueue self
end
def before(job)
Delayed::Job.where("last_error is NULL AND queue = ? AND created_at < ?", job.queue, DateTime.now).delete_all
end
end
类更新AzuReviedeOSJob
我删除同一队列中以前的作业的原因是,当我在perform中调用enqueue方法时,它会添加一个额外的作业,然后再添加一个额外的作业,并且包含计划作业的队列会很快变脏
我只是在试验,这可能是我的案例中最接近的解决方法(尽管有点傻)。我没有尝试过其他的选择,但任何建议都将不胜感激。谢谢。我就是这样做的:
def after(job)
Delayed::Job.transaction do
Delayed::Job.create(handler: job.handler, queue: job.queue, run_at: job.run_at + 5.minutes)
job.destroy
end
end
它将重新安排作业在原始作业完成后每5分钟运行一次。今年大部分时间都在生产中使用,没有出现任何问题。在
#error(job)
回调中也有相同的逻辑这不是更适合cron
作业或单个后台脚本吗?如果您希望作业无限期地重新运行,那么一遍又一遍地将后台任务重新排队似乎毫无意义。或者,为什么不在AzureVideo
获取state=5
时将作业排队,并将该id/模型作为参数传入呢?那么您就不需要像这样一直轮询整个记录集了。旁注1:执行.all.map{…}.compact
效率极低。您应该使用.where.not(状态:5)
侧注2:to\u update.empty?检查是多余的。如果数组为空,则。每个都不会产生任何结果。旁注3:枚举的全部目的是将“人类友好的名称”映射为“计算机友好的”数字。您不应该在代码中引用state=5
,而应该引用枚举中调用的任何内容。-您现在所做的工作是可行的,但它忽略了此技术的一个主要好处。