我有一个冗长的任务需要在我的Rails 4.2.6应用程序中在后台运行.不幸的是,使用Active Job不会将作业发送到后台.我创造了一份工作:
class PhotoProcessorJob < ActiveJob::Base queue_as :default def perform(*args) ::Photo.process_photos end end
它调用我的Photo类上的方法(存储在config / initializers中):
class Photo require 'zxing' require 'csv' @tablePath = Dir.glob("#{Rails.root.to_s}/tmp/photo_processing/*.csv")[0] @output = "#{Rails.root.to_s}/tmp/photo_data.csv" def self.getStudentInfo(id) CSV.foreach(@tablePath,headers: true) do |row| if row["Student ID"] == id return row else next end end end def self.writeInfoToFile(data,file) first_name = data["First Name"] last_name = data["Last Name"] student_id = data["Student ID"] grade = data["Grade"] email = data["Email"] photo = file.to_s CSV.open(@output,"a+") do |csv| csv << [first_name,last_name,student_id,grade,email,photo] end end def self.process_photos extensions = %w(.jpg .jpeg .png .gif .tif) studentInfo = nil newfile = false if File.exist?(@output) outfile = CSV.new(File.read(@output)) if outfile.count == 0 newfile = true end else newfile = true end if newfile CSV.open(@output,"wb") do |csv| csv << ["First Name","Last Name","Student ID","Grade","Email","Photo"] end end Dir.glob("#{Rails.root.to_s}/tmp/photo_processing/*").each do |file| if file.match(/#{extensions.join("|")}/) id = ZXing.decode File.new(file) unless id.nil? studentInfo = getStudentInfo(id) else writeInfoToFile(studentInfo,file) unless studentInfo.nil? end end end end end
并从控制器调用:
class ProcessingController < ApplicationController def finish PhotoProcessorJob.perform_later end end
我正在尝试使用Active Job Inline后端,因此没有安装任何队列库.问题是“完成”视图在process_photos方法运行时被延迟,而不是被发送到后台并且视图立即显示.这导致由上游过早关闭连接引起的Nginx内的502错误,可能是因为process_photos任务花费的时间太长而无法完成.
我的Active Job设置有问题吗?
解决方法
引用文档:
Rails by default comes with an “immediate runner” queuing implementation. That means that each job that has been enqueued will run immediately.
这意味着默认情况下,活动作业将在主线程中运行,而不是在“后台”中运行.这是一个常见的问题.基本上,活动作业只是跨多个排队后端的通用API.
TL; DR您必须设置像Sidekiq这样的排队后端.
否则,你的设置看起来很棒,教科书甚至.