简体   繁体   English

Rails 4多线程和connection_pool问题

[英]Rails 4 multithreading and connection_pool problems

I am trying to multithread my rails application but have run into some issues with connection_pool. 我正在尝试对Rails应用程序进行多线程处理,但是遇到了connection_pool的一些问题。 I start a thread and execute a database query but it never seems like the database connections created in the thread are closed. 我启动一个线程并执行数据库查询,但是似乎从来没有关闭该线程中创建的数据库连接。 This is my code: 这是我的代码:

class A
def self.foo
    Thread.new do
      nc1 = ActiveRecord::Base.connection_pool.connections.size
      nw = ""
      nc2 = ""

      ActiveRecord::Base.connection_pool.with_connection do |conns|
        nw = Person.count
        nc2 = ActiveRecord::Base.connection_pool.connections.size
      end

      nc3 = ActiveRecord::Base.connection_pool.connections.size
      puts "First there were #{nc1} connections, after things there were #{nc2} and now finally there are #{nc3} connections, there are #{nw} people in the db"  
    end
  end 
end

When I execute 10.times {A.foo} it gives me this output. 当我执行10次{A.foo}时,它给出了这个输出。

First there were 1 connections, after things there were 3 and now finally there are 5 connections, there are 5325 people in the db
First there were 1 connections, after things there were 4 and now finally there are 5 connections, there are 5325 people in the db
First there were 1 connections, after things there were 2 and now finally there are 5 connections, there are 5325 people in the db
First there were 1 connections, after things there were 5 and now finally there are 5 connections, there are 5325 people in the db
First there were 1 connections, after things there were 5 and now finally there are 5 connections, there are 5325 people in the db
First there were 1 connections, after things there were 5 and now finally there are 5 connections, there are 5325 people in the db
First there were 1 connections, after things there were 5 and now finally there are 5 connections, there are 5325 people in the db
First there were 1 connections, after things there were 5 and now finally there are 5 connections, there are 5325 people in the db
First there were 1 connections, after things there were 5 and now finally there are 5 connections, there are 5325 people in the db
First there were 1 connections, after things there were 5 and now finally there are 5 connections, there are 5325 people in the db

And the finally i run: 最后我跑了:

ActiveRecord::Base.connection_pool.connections.size
5

Now according to the documentation with_connection is supposed to take a block and execute it with a connection which it then closes, but according to my output it doesn't. 现在,根据文档, with_connection应该包含一个块并使用连接将其执行,然后关闭该连接,但是根据我的输出,它没有。 I really don't get it. 我真的不明白。

Does anybody have any solutions or ideas why this might be happening? 是否有人有任何解决方案或想法可能会发生这种情况? Is using "connection_pool.connections.size" the right way of checking how many connections there are? 使用“ connection_pool.connections.size”是检查多少个连接的正确方法吗?

Is there some other way to achieve multithreaded database queries in rails? 还有其他方法可以在Rails中实现多线程数据库查询吗?

Ok so I just did not understant how connection_pool works. 好的,所以我只是不了解connection_pool的工作方式。 Connection pool holds the connections that have been opened since the pool was created whether they are being used or not. 连接池保存自创建该池以来已打开的连接,无论是否正在使用它们。 So the answer to my question is that you cannot (with the way it is implemented today) connection_pool to see which connections are being actively used. 因此,我的问题的答案是,您(无法通过今天实现的方式)无法通过connection_pool查看正在积极使用的连接。 Instead I patched the connection pool itself to include this functionality. 相反,我修补了连接池本身以包括此功能。

If anyone is interested this is my patch placed in config/initializers/connection_pool_patch.rb: 如果有人感兴趣,这是我的补丁放在config / initializers / connection_pool_patch.rb中:

module ActiveRecord
  module ConnectionAdapters
    class ConnectionPool
      def num_available
        @available.size
      end
    end
  end
end

module ActiveRecord
  module ConnectionAdapters
    class ConnectionPool
      class Queue
        def size
          @queue.size
        end
      end
    end
  end
end

It exposes the size of the private list @available that holds the available (ie not currently used but opened) connections in the connection pool. 它公开了私有列表@available的大小,该私有列表在连接池中保存了可用(即,当前未使用但已打开)的连接。 Usage = ActiveRecord::Base.connection_pool.num_available 用法= ActiveRecord :: Base.connection_pool.num_available

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM