Threaded DelayedJob工作人员干掉了ActiveRecord连接池

时间:2017-11-17 12:05:28

标签: ruby multithreading activerecord delayed-job rufus-scheduler

我想在同一个jRuby进程中使用ActiveRecord后端运行作业调度(使用rufus_scheduler)和处理(使用delayed_job,DJ),但是在不同的线程中。

当只使用一个DJ工作程序时这很好用,但是当我设置多个队列(每个队列有一个工作程序)时,调度程序终止时会显示以下消息:

rufus-scheduler intercepted an error:                                                                               
   job:                                                                                                                          
     Rufus::Scheduler::CronJob "*/10 * * * * *" {}                                                                   
   error:                                                                                                            
     ActiveRecord::ConnectionTimeoutError                                                                             
     could not obtain a connection from the pool within 5.000 seconds (waited 5.000 seconds); all pooled connections were in use

这让我相信工作人员在作业终止时不会释放数据库连接,但我还没有找到相关的代码。池中的连接数配置为50。

该脚本应该继续运行,直到它收到SIGTERM并且应该可以访问Rails环境。 MWE如下:

require './config/environment'

module Jobs
  class ExampleJob < ActiveJob::Base
    queue_as :system

    def perform
      puts 'Performing ExampleJob'
    end
  end
end

QUEUES = %i(system database).freeze
NUM_QUEUES = QUEUES.size

workers = []
worker_threads = []

NUM_QUEUES.times do |queue_number|
  worker = Delayed::Worker.new(quiet: false)
  worker.name = queue_number
  workers.append(worker)
  worker_threads.append(Thread.new do
    worker.start
  end)
end

scheduler = Rufus::Scheduler.new

scheduler.cron '*/10 * * * * *' do
  puts 'Scheduled ExampleJob'
  Jobs::ExampleJob.perform_later
end

Signal.trap('TERM') do
  scheduler.shutdown
  workers.each do |worker|
    worker.stop
  end
end

scheduler.join
worker_threads.each do |thread|
  thread.join
end

有没有办法让它正常运行?

1 个答案:

答案 0 :(得分:0)

怎么样

module Jobs
  class ExampleJob < ActiveJob::Base
    queue_as :system

    def perform
      puts 'Performing ExampleJob'
    end

    after_perform do
      ActiveRecord::Base.clear_active_connections!
    end
  end
end