About mongodb ruby driver different behaviour for replicaset and non-replicaset

51 views
Skip to first unread message

xiangjun wu

unread,
Oct 12, 2012, 3:48:45 AM10/12/12
to mongod...@googlegroups.com
Dear folks,

Question1: from mongodb wiki https://github.com/mongodb/mongo-ruby-driver

Forking

Certain Ruby application servers work by forking, and it has long been necessary to re-establish the child process's connection to the database after fork. But with the release of v1.3.0, the Ruby driver detects forking and reconnects automatically.


Can you tell us where I can find proper codes in mongo driver for automatically reconnection?

Question2:  see the following logic  when passenger fork new rack.

if defined?(PhusionPassenger)
  PhusionPassenger.on_event( :starting_worker_process ) do |forked|
    MongoMapper.connection.connect if forked
  end
end

It will call connect method to set up connection.
But there are two different behaviour for replica set and non-reaplicaset:

Replicaset connect method:
def connect
     log(:info, "Connecting...")
     return if @connected

     discovered_seeds = @manager ? @manager.seeds : []
     @manager = PoolManager.new(self, discovered_seeds)

     @manager.connect
     @refresh_version += 1

     if @require_primary && self.primary.nil? #TODO: in v2.0, we'll let this be optional and do a lazy connect.
       close
       raise ConnectionFailure, "Failed to connect to primary node."
     elsif self.read_pool.nil?
       close
       raise ConnectionFailure, "Failed to connect to any node."
     else
       @connected = true
     end
   end
end

Non-replica set connect method:
def connect
     close
     config = check_is_master(@host_to_try)
     if config
       if config['ismaster'] == 1 || config['ismaster'] == true
         @read_primary = true
       elsif @slave_ok
         @read_primary = false
       end

       @max_bson_size = config['maxBsonObjectSize'] || Mongo::DEFAULT_MAX_BSON_SIZE
       set_primary(@host_to_try)
     end
     if !connected?
       raise ConnectionFailure, "Failed to connect to a master node at #{@host_to_try[0]}:#{@host_to_try[1]}"
     end
   end

Replicaset connect method may not close connection when @connected = true,
Non-replicaset connect method always close connection and connect again.
We want to know if there is some special consideration.

So, for replicaset case, potentially forked process may share the same connections with other old rack process. It is not allowed.

Jeremy Mikola

unread,
Oct 12, 2012, 4:52:21 PM10/12/12
to mongod...@googlegroups.com


On Friday, October 12, 2012 3:48:45 AM UTC-4, xiangjun wu wrote:

Question1: Can you tell us where I can find proper codes in mongo driver for automatically reconnection?

See: https://jira.mongodb.org/browse/RUBY-250 ("Automatically create a new socket on fork")

The following commits are related to that issue:

 

Question2:  

Replicaset connect method may not close connection when @connected = true,
Non-replicaset connect method always close connection and connect again.
We want to know if there is some special consideration.

So, for replicaset case, potentially forked process may share the same connections with other old rack process. It is not allowed.

Since the fork reconnections are handled at the connection pool level, I don't believe forked processes with RS connections would behave any differently. Have you tested this and found that not to be the case?
Reply all
Reply to author
Forward
0 new messages