1

I'm seeing some sort of weird issue which I'm trying to understand, the first part of that issue is trying to understand how is Database Pool work in Celluloid vs Celluloid/ZMQ.

Database Pool.

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

Notice that, I'm output(ting) the connection id that was used by the thread. 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     ...

As you can see a different connection id is returned by each thread that executed the SQL statement. SELECT version();

Above is perfectly valid as per my assumption.

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       ...

Again, as expected each Celluloid actor resulted in a new connection id. Perfectly valid.

3) Celluloud/ZMQ

  • The sender (a.k.a Client)
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
  • The Receiver(a.k.a Server)
     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

Now, the fun part. Upon executing this.

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

I see the following output.

{"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

All query uses the same connection id.

And this is what my question is ...

How come Celluloid/ZMQ uses same connection id. Ideally, it should be using a different for each async call.

digitalextremist
  • 5,952
  • 3
  • 43
  • 62
Viren
  • 5,812
  • 6
  • 45
  • 98

1 Answers1

0

Because one Receiver is serving many Sender instances.

Take note: Sender in the Celluloid::ZMQ example, does not handle the record itself. Many give them to one receiver. Therefore, you are seeing the connection being used exclusively by Receiver which is also valid behavior, as given.

If you want it to be different -- you will need a third type of actor who purely handles a single database connection in its lifetime. That'd be sort of a combination of your first two approaches and your last one.

digitalextremist
  • 5,952
  • 3
  • 43
  • 62
  • I was assuming that `.async` would use a new connection id from pool at least that is what I see in plain celluloid example. So why does it behave differently in celluloid/zmq – Viren Apr 14 '16 at 12:09
  • What is your `ActiveRecord` configuration code, creating a connection pool? – digitalextremist Apr 14 '16 at 12:13
  • Nope I don't have any configuration code I was planning to use ActiveRecord::Connection.. `with_connection` before I stumble upon the above issue. Which highlighted me that `async` in celluloid zmq using same connection id – Viren Apr 14 '16 at 12:34
  • Can explain the above stuff in more detail as also the fact why pure Celluloid create a new connection_id every time when called with async and Celluloid/ZMQ async doesn't – Viren Apr 15 '16 at 16:24