ruby 关闭Rails ActiveRecord连接池

vaj7vani  于 2023-01-08  发布在  Ruby
关注(0)|答案(2)|浏览(145)

我正在使用第二个数据库,其中包含我的API中的数据集。
每个API请求可以有多达3个查询的数据库,所以我把他们分为三个线程。为了保持线程安全,我使用了一个连接池。
但是在整个代码运行之后,ConnectionPool线程并没有终止,所以基本上每次发出请求时,服务器上都会有一个新的线程,直到基本上没有内存剩余。
有没有办法关闭连接池线程?或者我在为每个请求创建连接池时做错了什么?
我这样设置连接池:

begin
  full_db = YAML::load(ERB.new(File.read(Rails.root.join("config","full_datasets_database.yml"))).result)
  resolver = ActiveRecord::ConnectionAdapters::ConnectionSpecification::Resolver.new(full_db)
  spec = resolver.spec(Rails.env.to_sym)
  pool = ActiveRecord::ConnectionAdapters::ConnectionPool.new(spec)

然后,我运行queries数组并将结果获取到查询中

returned_responses = []
queries_array.each do |query|
  threads << Thread.new do
    pool.with_connection do |conn|
     returned_responses << conn.execute(query).to_a
    end
  end
end

threads.map(&:join)

returned_responses

最后,关闭连接池中的连接:

ensure
 pool.disconnect!
end
gopyfrb3

gopyfrb31#

遵循Rails中处理多个数据库的官方方法:
https://guides.rubyonrails.org/active_record_multiple_databases.html
我不能给予你一个准确的答案,因为我没有你的源代码,以充分了解整个上下文。如果我发送以上设置不适用于您的用例,您可能会错过一些后台清理任务。您可以参考以下文档:
https://api.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters/ConnectionPool.html

pu82cl6c

pu82cl6c2#

由于您希望直接进行SQL查询,而不利用ActiveRecord作为ORM,但您确实希望利用ActiveRecord连接池,因此我建议您创建一个新的抽象类,如ApplicationRecord

# app/models/full_datasets.rb

class FullDatasets < ActiveRecord::Base
  self.abstract_class = true

  connects_to database: {
    writing: :full_datasets_database,
    reading: :full_datasets_database
  }
end

您需要在database.yml中配置数据库full_datasets_database,以便connects_to能够连接到它。
然后,您将能够直接连接到该数据库,并通过引用该类而不是ActiveRecord::Base对它进行直接SQL查询:

FullDatasets.connection.execute(query)

连接池将透明地与不同的池一起发生:

FullDatasets.connection_pool.object_id
=> 22620

ActiveRecord::Base.connection_pool.object_id
=> 9000

您可能需要进行额外的配置,比如将模式转储到db/full_datasets_schema.rb,但是您需要进行的任何额外的故障排除或配置都将在https://guides.rubyonrails.org/active_record_multiple_databases.html中进行描述。
简短的解释是,您应该尽可能多地利用ActiveRecord,以便您的实现干净而直接,同时仍然允许您直接使用原始SQL。

相关问题