我有一个小的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
博客文章