Start or ensure that Delayed Job runs when an application/server restarts

前端 未结 4 606
被撕碎了的回忆
被撕碎了的回忆 2020-12-28 20:27

We have to use delayed_job (or some other background-job processor) to run jobs in the background, but we\'re not allowed to change the boot scripts/boot-levels on the serve

4条回答
  •  忘掉有多难
    2020-12-28 20:51

    Thank you for the solution provided in the question (and the answer that inspired it :-) ), it works for me, even with multiple workers (Rails 3.2.9, Ruby 1.9.3p327).

    It worries me that I might forget to restart delayed_job after making some changes to lib for example, causing me to debug for hours before realizing that.

    I added the following to my script/rails file in order to allow the code provided in the question to execute every time we start rails but not every time a worker starts:

    puts "cleaning up delayed job pid..."
    dj_pid_path = File.expand_path('../../tmp/pids/delayed_job.pid',  __FILE__)
    begin
      File.delete(dj_pid_path)
    rescue Errno::ENOENT # file does not exist
    end
    puts "delayed_job ready."
    

    A little drawback that I'm facing with this though is that it also gets called with rails generate for example. I did not spend much time looking for a solution for that but suggestions are welcome :-)

    Note that if you're using unicorn, you might want to add the same code to config/unicorn.rb before the before_fork call.

    -- EDITED: After playing around a little more with the solutions above, I ended up doing the following:

    I created a file script/start_delayed_job.rb with the content:

    puts "cleaning up delayed job pid..."
    dj_pid_path = File.expand_path('../../tmp/pids/delayed_job.pid',  __FILE__)
    
    def kill_delayed(path)
      begin
        pid = File.read(path).strip
        Process.kill(0, pid.to_i)
        false
      rescue
        true
      end
    end
    
    kill_delayed(dj_pid_path)
    
    begin
      File.delete(dj_pid_path)
    rescue Errno::ENOENT # file does not exist
    end
    
    # spawn delayed
    env = ARGV[1]
    puts "spawing delayed job in the same env: #{env}" 
    
    # edited, next line has been replaced with the following on in order to ensure delayed job is running in the same environment as the one that spawned it
    #Process.spawn("ruby script/delayed_job start")
    system({ "RAILS_ENV" => env}, "ruby script/delayed_job start")
    
    puts "delayed_job ready."
    

    Now I can require this file anywhere I want, including 'script/rails' and 'config/unicorn.rb' by doing:

    # in top of script/rails
    START_DELAYED_PATH = File.expand_path('../start_delayed_job',  __FILE__)
    require "#{START_DELAYED_PATH}"
    
    # in config/unicorn.rb, before before_fork, different expand_path
    START_DELAYED_PATH = File.expand_path('../../script/start_delayed_job',  __FILE__)
    require "#{START_DELAYED_PATH}"
    

提交回复
热议问题