RUBY-379 RUBY-381 reconnect on 'not master' errors (fix close connection logic)

This commit is contained in:
Kyle Banker 2011-12-05 15:25:37 -05:00
parent c25b1f1585
commit b6ff77fcbc
5 changed files with 34 additions and 25 deletions

View File

@ -458,12 +458,13 @@ module Mongo
@primary_pool
end
# The value of the read preference. Because
# this is a single-node connection, the value
# is +:primary+, and the connection will read
# from whichever type of node it's connected to.
# The value of the read preference.
def read_preference
:primary
if slave_ok?
:secondary
else
:primary
end
end
# Close the connection to the database.

View File

@ -86,7 +86,7 @@ module Mongo
if(!@timeout)
add_option(OP_QUERY_NO_CURSOR_TIMEOUT)
end
if(@connection.slave_ok?)
if(@read_preference != :primary)
add_option(OP_QUERY_SLAVE_OK)
end
if(@tailable)
@ -136,7 +136,7 @@ module Mongo
# If the server has stopped being the master (e.g., it's one of a
# pair but it has died or something like that) then we close that
# connection. The next request will re-open on master server.
if err == "not master"
if err.include?("not master")
@connection.close
raise ConnectionFailure.new(err, doc['code'], doc)
end

View File

@ -205,7 +205,7 @@ module Mongo
def hard_refresh!
log(:info, "Initiating hard refresh...")
discovered_seeds = @manager ? @manager.seeds : []
background_manager = PoolManager.new(self, discovered_seeds | @original_seeds)
background_manager = PoolManager.new(self, discovered_seeds | @seeds)
background_manager.connect
# TODO: make sure that connect has succeeded
@ -218,7 +218,7 @@ module Mongo
end
def connected?
self.primary_pool || self.read_pool
@connected && (self.primary_pool || self.read_pool)
end
# @deprecated
@ -261,9 +261,13 @@ module Mongo
end
# Close the connection to the database.
def close
def close(opts={})
if opts[:soft]
@manager.close(:soft => true) if @manager
else
@manager.close if @manager
end
@connected = false
@manager.close(:soft => true) if @manager
end
# If a ConnectionFailure is raised, this method will be called
@ -348,8 +352,8 @@ module Mongo
# Checkin a socket used for reading.
def checkin_reader(socket)
if !self.read_pool.checkin(socket) &&
!self.primary_pool.checkin(socket)
if !((self.read_pool && self.read_pool.checkin(socket)) ||
(self.primary_pool && self.primary_pool.checkin(socket)))
close_socket(socket)
end
sync_refresh
@ -365,7 +369,7 @@ module Mongo
def close_socket(socket)
begin
socket.close
socket.close if socket
rescue IOError
log(:info, "Tried to close socket #{socket} but already closed.")
end
@ -388,36 +392,40 @@ module Mongo
end
def primary
@manager.primary
@manager ? @manager.primary : nil
end
# Note: might want to freeze these after connecting.
def secondaries
@manager.secondaries
@manager ? @manager.secondaries : []
end
def hosts
@manager.hosts
@manager ? @manager.hosts : []
end
def primary_pool
@manager.primary_pool
@manager ? @manager.primary_pool : nil
end
def read_pool
@manager.read_pool
@manager ? @manager.read_pool : nil
end
def secondary_pools
@manager.secondary_pools
@manager ? @manager.secondary_pools : []
end
def tag_map
@manager.tag_map
@manager ? @manager.tag_map : {}
end
def max_bson_size
@manager.max_bson_size
if @manager && @manager.max_bson_size
@manager.max_bson_size
else
Mongo::DEFAULT_MAX_BSON_SIZE
end
end
private

View File

@ -109,7 +109,7 @@ module Mongo
# The set of nodes that this class has discovered and
# successfully connected to.
def seeds
@seeds
@seeds || []
end
private
@ -280,7 +280,7 @@ module Mongo
end
raise ConnectionFailure, "Cannot connect to a replica set using seeds " +
"#{@seeds.map {|s| "#{s[0]}:#{s[1]}" }.join(', ')}"
"#{seed_list.map {|s| "#{s[0]}:#{s[1]}" }.join(', ')}"
end
def seed_list

View File

@ -5,7 +5,7 @@ class ReplicaSetQueryTest < Test::Unit::TestCase
include ReplicaSetTest
def setup
@conn = ReplSetConnection.new([self.rs.host, self.rs.ports[0], self.rs.ports[1]])
@conn = ReplSetConnection.new([self.rs.host, self.rs.ports[0]])
@db = @conn.db(MONGO_TEST_DB)
@db.drop_collection("test-sets")
@coll = @db.collection("test-sets")