数据库池CelluloidZMQ vs Celluloid vs Thread

时间:2016-04-14 10:49:31

标签: ruby multithreading postgresql activerecord celluloid

我正在看到一些我想要了解的奇怪问题,该问题的第一部分是试图了解数据库池在Celluloid与Celluloid / ZMQ中的工作原理。

数据库池。

1)THREAD。

 5.times do 
   Thread.new do 
      puts "#{ActiveRecord::Base.connection.execute('SELECT version();').first} --- #{ActiveRecord::Base.connection_id}"
      sleep 5
   end
 end
 sleep

请注意,我输出(ting)线程使用的connection id。  O / P

{"version"=>"PostgreSQL 9.4.5 .."} --- 70115833371600 <- connection id
{"version"=>"PostgreSQL 9.4.5 .."} --- 70115833339020 <- connection id
{"version"=>"PostgreSQL 9.4.5 .."} --- 70115833290000     ...  
{"version"=>"PostgreSQL 9.4.5 .."} --- 70115833282580     ...
{"version"=>"PostgreSQL 9.4.5 .."} --- 70115833251100     ...

正如您所看到的,执行SQL语句的每个线程都返回不同的连接ID。 SELECT version();

根据我的假设,上述内容完全有效。

2)CELLULOID

class PlainCelluloid
  include Celluloid

  def run
    puts "#{ActiveRecord::Base.connection.execute('SELECT version();').first} --- #{ActiveRecord::Base.connection_id}"
    sleep 5
  end
end

5.times do 
 Sender.new.async.run
end

O / P

{"version"=>"PostgreSQL 9.4.5 .."} --- 70120202935840  <- connection id
{"version"=>"PostgreSQL 9.4.5 .."} --- 70120202902760  <- connection id
{"version"=>"PostgreSQL 9.4.5 .."} --- 70120186634700       ...
{"version"=>"PostgreSQL 9.4.5 .."} --- 70120186602720       ...
{"version"=>"PostgreSQL 9.4.5 .."} --- 70120186570720       ...

同样,按预期每个Celluloid actor都会产生一个新的连接ID。完全有效。

3)Celluloud / ZMQ

  • 发件人(a.k.a客户)
class Sender
  include Celluloid::ZMQ

  def initialize()
   @socket = Socket::Push.new
   @socket.connect('ipc:///tmp/qs11')
  end

  def write
   @socket.send('Hello')
  nil
  end
end
  • 接收者(a.k.a服务器)
     class Receiver

      include Celluloid::ZMQ
      def initialize()
        @socket = Socket::Pull.new
          @socket.bind('ipc:///tmp/qs11')
      end

      def run
       loop do 
        async.handle_message @socket.read
       end    
     end

     def handle_message(message)
       puts "#{ActiveRecord::Base.connection.execute('SELECT version();').first} --- #{ActiveRecord::Base.connection_id}"
       sleep 10
       end
    end

    Receiver.new.async.run

现在,有趣的部分。执行此操作后。

5.times do 
  Sender.new.async.write
end

我看到以下输出。

{"version"=>"PostgreSQL 9.4.5 ..."} --- 70299372892280  <- connection id
{"version"=>"PostgreSQL 9.4.5 ..."} --- 70299372892280
{"version"=>"PostgreSQL 9.4.5 ..."} --- 70299372892280
{"version"=>"PostgreSQL 9.4.5 ..."} --- 70299372892280
{"version"=>"PostgreSQL 9.4.5 ..."} --- 70299372892280

所有查询都使用相同的连接ID。

这就是我的问题......

Celluloid/ZMQ如何使用相同的连接ID。 理想情况下,每个async调用应该使用不同的。

1 个答案:

答案 0 :(得分:0)

因为一个Receiver正在为许多Sender个实例提供服务。

请注意:Sender示例中的Celluloid::ZMQ不会处理记录本身​​。许多人将它们交给一个接收器。因此,您看到Receiver专门使用的连接也是有效行为,如给定的那样。

如果您希望它与众不同 - 您将需要第三种类型的actor,它在其生命周期内纯粹处理单个数据库连接。这可能是前两种方法和最后一种方法的组合。