Rails ActiveRecord with_connection空闲数据库连接泄露?

时间:2018-03-07 06:26:29

标签: ruby-on-rails multithreading postgresql activerecord database-connection

我有一个小的rails应用程序,它会生成新的线程,以便在后台更新自己,直到满足某个条件。

class SomeModel < ApplicationRecord
  def self.some_action
    if some_condition
      Thread.new do
        begin
          sleep some_arbitrary_time
          ActiveRecord::Base.connection_pool.with_connection do
            update(attr_x: true)
            some_action
          end
        ensure
          ActiveRecord::Base.connection_pool.release_connection
        end
      end
    end
  end
end

我尝试了ActiveRecord::with_connection releasing closing个连接,但最终总是有空闲连接。

检查db或ActiveRecord是否显示多个空闲连接

db_development=# select state from pg_stat_activity where pid <> pg_backend_pid();
 state
-------
 idle
 idle
 idle
 idle

ActiveRecord::Base.connection_pool.stat
{"size":10,"connections":5,"busy":1,"dead":0,"idle":4,"waiting":0,"checkout_timeout":5}

据我了解,reaping进程只处理死连接,空闲连接将留在那里消耗池资源。

一个更简单的示例(基于特定的rails issue)表明在使用新线程和with_connection之后存在空闲进程。

考试前

collab-playlist_development=# select state from pg_stat_activity where pid <> pg_backend_pid();
 state
-------
(0 rows)

20.times.map do 
  Thread.new do 
    ActiveRecord::Base.connection_pool.with_connection do 
      SomeModel.count 
      end 
    end 
  end

考试后

db_development=# select state from pg_stat_activity where pid <> pg_backend_pid();
 state
-------
 idle
 idle
 idle
 idle
 idle
 idle
 idle
 idle
 idle
 idle

ActiveRecord::Base.connection_pool.stat
{"size":10,"connections":10,"busy":0,"dead":0,"idle":10,"waiting":0,"checkout_timeout":5}

有没有办法关闭这些空闲连接以释放池资源?

一些参考文献(除了rails doc之外)对这个问题有所了解,但没有解决方案:

SO

博客文章

0 个答案:

没有答案