通过在应用程序启动时启动worker来初始化Delayed Jobs gem

我正在使用Ruby on Rails 3.0.9,我正在尝试设置delay_job gem。 如果在重新启动Apache2服务器后,我按照以下命令在Terminal \ Console中运行,则一切正常:

RAILS_ENV=development script/delayed_job stop RAILS_ENV=development script/delayed_job -n 2 start 

但是,因为我总是希望在应用程序启动时启动worker,在我的config/initializers/delayed_job.rb添加以下代码(处理开发和生产模式):

 if Rails.env.development? system 'RAILS_ENV=development script/delayed_job stop' system 'RAILS_ENV=development script/delayed_job -n 2 start' elsif Rails.env.production? system 'RAILS_ENV=production script/delayed_job stop' system 'RAILS_ENV=production script/delayed_job -n 2 start' end 

但是,通过使用上面的代码并在重新启动Apache2服务器后,DJ gem不再按预期工作。 也就是说,当我在Terminal \ Console中运行上述命令行时,它不会处理作业。

如何让DJ正常工作? 问题是什么?

PS:我想这样做是为了使流程自动化。


它认为config/initializers/delayed_job.rb文件中的上述代码没有“创建” RAILS_ROOT/tmp/pids目录中与DJ相关的“pids”文件。 这些只能通过手动运行上述命令行来创建。 为什么会这样?


@Devin M的 更新

我的config/initializers/delayed_job.rb包含:

 # Options Delayed::Worker.destroy_failed_jobs = false Delayed::Worker.sleep_delay = 2 Delayed::Worker.max_attempts = 5 Delayed::Worker.max_run_time = 1.hour Delayed::Worker.delay_jobs = !Rails.env.test? if Rails.env.development? system "RAILS_ENV=development #{Rails.root.join('script','delayed_job')} stop" system "RAILS_ENV=development #{Rails.root.join('script','delayed_job')} -n 2 start" elsif Rails.env.production? system "RAILS_ENV=production #{Rails.root.join('script','delayed_job')} stop" system "RAILS_ENV=production #{Rails.root.join('script','delayed_job')} -n 2 start" end 

尝试使用此代码:

 system "RAILS_ENV=production #{Rails.root.join('script','delayed_job')} stop" system "RAILS_ENV=production #{Rails.root.join('script','delayed_job')} -n 2 start" 

在控制台中测试它产生了这个输出,表明它应该工作:

 Loading development environment (Rails 3.0.9) ruby-1.9.2-p290 :001 > Rails.root.join('script','delayed_job') => # ruby-1.9.2-p290 :002 > "RAILS_ENV=production #{Rails.root.join('script','delayed_job')} -n 2 start" => "RAILS_ENV=production /home/devin/testsoapp/script/delayed_job -n 2 start" ruby-1.9.2-p290 :003 > 

我认为你不能这样做,因为当你启动’/ script / delayed_job’时,将加载rails环境,导致’config / initializers / delayed_job.rb’文件再次被执行。 您可以在无限循环中看到此结果。 每次调用rake时,例如:’rake db:migrate’,它都会初始化delayed_jobs。

你可以用这个来解决它:

 if Rails.env.production? if(!File.exists?(Rails.root.join('tmp','pids', 'delayed_job.pid'))) system "echo \"Starting delayed_jobs...\"" system "./script/delayed_job start &" else system "echo \"delayed_jobs is running\"" end end 

使用’&’,delayed_job脚本在后台运行,与rails不同。 如果已经运行,对rake的后续调用将跳过启动delayed_jobs。 如果由于某种原因,在delayed_jobs终止时不删除该文件,您仍会遇到一些问题。

命令/ script / delayed_job状态将检测是否是这种情况,但你不能在这个’config / initializers / delayed_job.rb’文件中运行它,因为它会导致无限循环:(

我有一个问题,在创建pid文件之前初始化delayed_job进程正在运行它的初始化程序(例如,对于单个工作程序,则为delayed_job.pid;对于许多工作程序,则为delayed_job.0.pid delayed_job.1.pid等)

所以我使用这样创建自己的锁文件:

 Delayed::Worker.destroy_failed_jobs = false Delayed::Worker.sleep_delay = 2 Delayed::Worker.max_attempts = 5 Delayed::Worker.max_run_time = 4.hour Delayed::Worker.delay_jobs = !Rails.env.test? workers = 2 if Rails.env.production? || Rails.env.development? # Check if the delayed job process is already running # Since the process loads the rails env, this file will be called over and over # Unless this condition is set. pids = Dir.glob(Rails.root.join('tmp','pids','*')) system "echo \"delayed_jobs INIT check\"" if pids.select{|pid| pid.start_with?(Rails.root.join('tmp','pids','delayed_job.init').to_s)}.empty? f = File.open(Rails.root.join('tmp','pids','delayed_job.init'), "w+") f.write(".") f.close system "echo \"Restatring delayed_jobs...\"" system "RAILS_ENV=#{Rails.env} #{Rails.root.join('bin','delayed_job')} stop" system "RAILS_ENV=#{Rails.env} #{Rails.root.join('bin','delayed_job')} -n #{workers} start" system "echo \"delayed_jobs Workers Initiated\"" File.delete(Rails.root.join('tmp','pids','delayed_job.init')) if File.exist?(Rails.root.join('tmp','pids','delayed_job.init')) else system "echo \"delayed_jobs is running\"" end end 

file:config \ initializers \ delayed_job.rb

注意:不适用于Windows!