Fix connection leak and refresh.

This commit is contained in:
Kyle Banker 2011-10-14 09:52:11 -04:00
parent 1001e59e44
commit 6a7e991689
5 changed files with 35 additions and 21 deletions

View File

@ -186,28 +186,25 @@ module Mongo
end
end
# Refresh the current replica set configuration.
# This method will attempt to do a soft refresh,
# updating only those parts of the replica set that
# have changed. If that's not possible, the method
# will perform a hard refresh.
# Determine whether a replica set refresh is
# required. If so, run a hard refresh. You can
# force a hard refresh by running
# ReplSetConnection#hard_refresh!
#
# @return [Boolean] +true+ if hard refresh
# occurred. +false+ is returned when unable
# to get the refresh lock.
# @return [Boolean] +true+ unless a hard refresh
# is run and the refresh lock can't be acquired.
def refresh(opts={})
if !connected?
log(:info, "Trying to refresh but not connected..." +
"skipping replica set health check.")
hard_refresh!
return true
log(:info, "Trying to check replica set health but not " +
"connected...")
return hard_refresh!
end
log(:info, "Checking replica set connection health...")
@manager.check_connection_health
if @manager.refresh_required?
hard_refresh!
return hard_refresh!
end
return true
@ -227,9 +224,12 @@ module Mongo
@background_manager.connect
sync_synchronize(:EX) do
@manager.close
update_config(@background_manager)
end
initiate_refresh_mode
return true
end
@ -360,6 +360,7 @@ module Mongo
@manager = manager
@nodes = manager.nodes
@max_bson_size = manager.max_bson_size
@sockets_to_pools.clear
end
def initiate_refresh_mode

View File

@ -56,7 +56,7 @@ module Mongo
def close
@connection_mutex.synchronize do
@sockets.each do |sock|
(@sockets - @checked_out).each do |sock|
begin
sock.close
rescue IOError => ex

View File

@ -47,6 +47,13 @@ module Mongo
config = seed.set_config
if !config
@refresh_required = true
seed.close
return
end
if config['hosts'].length != @members.length
@refresh_required = true
seed.close
return
end
@ -59,9 +66,12 @@ module Mongo
next
else
@refresh_required = true
seed.close
return false
end
end
seed.close
end
# The replica set connection should initiate a full refresh.

View File

@ -70,7 +70,7 @@ class ReplicaSetRefreshTest < Test::Unit::TestCase
rescue_connection_failure do
@conn = ReplSetConnection.new([RS.host, RS.ports[0]], [RS.host, RS.ports[1]],
[RS.host, RS.ports[2]], :refresh_interval => 2, :refresh_mode => :sync)
[RS.host, RS.ports[2]], :refresh_interval => 2, :refresh_mode => :async)
end
assert_equal [], @conn.secondaries
@ -78,8 +78,7 @@ class ReplicaSetRefreshTest < Test::Unit::TestCase
assert_equal @conn.read_pool, @conn.primary_pool
RS.restart_killed_nodes
sleep(3)
sleep(4)
assert @conn.read_pool != @conn.primary_pool, "Read pool and primary pool are identical."
assert @conn.secondaries.length > 0, "No secondaries have been added."
@ -87,9 +86,9 @@ class ReplicaSetRefreshTest < Test::Unit::TestCase
def test_automated_refresh_with_removed_node
@conn = ReplSetConnection.new([RS.host, RS.ports[0]], [RS.host, RS.ports[1]],
[RS.host, RS.ports[2]], :refresh_interval => 2, :refresh_mode => :sync)
[RS.host, RS.ports[2]], :refresh_interval => 2, :refresh_mode => :async)
p @conn.secondary_pools
@conn.secondary_pools
assert_equal 2, @conn.secondary_pools.length
assert_equal 2, @conn.secondaries.length
@ -107,7 +106,7 @@ class ReplicaSetRefreshTest < Test::Unit::TestCase
[RS.host, RS.ports[2]], :refresh_interval => 2, :refresh_mode => :async)
RS.add_node
sleep(5)
sleep(4)
@conn2 = ReplSetConnection.new([RS.host, RS.ports[0]], [RS.host, RS.ports[1]],
[RS.host, RS.ports[2]], :refresh_interval => 2, :refresh_mode => :async)
@ -116,8 +115,12 @@ class ReplicaSetRefreshTest < Test::Unit::TestCase
assert_equal 3, @conn.secondary_pools.length
assert_equal 3, @conn.secondaries.length
config = @conn['admin'].command({:ismaster => 1})
RS.remove_secondary_node
sleep(4)
config = @conn['admin'].command({:ismaster => 1})
assert_equal 2, @conn.secondary_pools.length
assert_equal 2, @conn.secondaries.length
end

View File

@ -158,7 +158,7 @@ class ReplSetManager
@config['version'] = config['version'] + 1
begin
con['admin'].command({'replSetReconfig' => @config})
con['admin'].command({'replSetReconfig' => @config})
rescue Mongo::ConnectionFailure
end