ruby - 数据库池 CelluloidZMQ vs Celluloid vs Thread

标签 ruby multithreading postgresql activerecord celluloid

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

数据库池。

1) 线程。

 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。 啊/啊

{"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) 赛璐珞

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

对/对

{"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) 蜂窝/ZMQ

  • 发件人(又名客户)
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
  • 接收者(又名服务器)
     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 调用使用不同的。

最佳答案

因为一个Receiver服务于多个Sender实例。

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

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

关于ruby - 数据库池 CelluloidZMQ vs Celluloid vs Thread,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36620856/

相关文章:

ruby-on-rails - 在@object.variable 的情况下,可以外推变量吗?

ruby-on-rails - Ruby on Rails 为时区中的 DateTime 对象设置特定时间

c# - 如果启动太多线程会怎样?

.net - UdpClient同时接收和发送

java - 将数据库表映射到 Java 类 - 依赖关系

sql - Postgres WHERE 两个数组有一个非空的交集

postgresql - go-gorm postgres 方言 : managing structs for jsonb insert and find to properly use json tags

ruby - Log4r 使用 yml 配置器 : The log message won't include trace

Ruby 散列活生生的怪异

c++ - 哪种类型的多线程最适合学习?