Skip to content

Commit

Permalink
RUBY-376 separate original seeds nodes from discovered ones
Browse files Browse the repository at this point in the history
  • Loading branch information
banker committed Dec 5, 2011
1 parent 221c40d commit c25b1f1
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 28 deletions.
27 changes: 12 additions & 15 deletions lib/mongo/repl_set_connection.rb
Original file line number Diff line number Diff line change
Expand Up @@ -91,8 +91,10 @@ def initialize(*args)
raise MongoArgumentError, "A ReplSetConnection requires at least one seed node."
end

# The list of seed nodes
# The original, immutable list of seed node.
# TODO: add a method for replacing this list of node.
@seeds = args
@seeds.freeze

# TODO: get rid of this
@nodes = @seeds.dup
Expand Down Expand Up @@ -152,11 +154,12 @@ def inspect
def connect
log(:info, "Connecting...")
return if @connected
manager = PoolManager.new(self, @seeds)
@manager = manager
manager.connect

update_config(manager)
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
Expand Down Expand Up @@ -201,13 +204,15 @@ def refresh(opts={})
# to get the refresh lock.
def hard_refresh!
log(:info, "Initiating hard refresh...")
background_manager = PoolManager.new(self, @seeds)
discovered_seeds = @manager ? @manager.seeds : []
background_manager = PoolManager.new(self, discovered_seeds | @original_seeds)
background_manager.connect

# TODO: make sure that connect has succeeded
old_manager = @manager
update_config(background_manager)
@manager = background_manager
old_manager.close(:soft => true)
@refresh_version += 1

return true
end
Expand Down Expand Up @@ -479,14 +484,6 @@ def setup(opts)
connect if should_connect
end

# Given a pool manager, update this connection's
# view of the replica set.
def update_config(new_manager)
@manager = new_manager
@seeds = @manager.seeds.dup
@refresh_version += 1
end

# Checkout a socket connected to a node with one of
# the provided tags. If no such node exists, raise
# an exception.
Expand Down
42 changes: 29 additions & 13 deletions lib/mongo/util/pool_manager.rb
Original file line number Diff line number Diff line change
@@ -1,30 +1,35 @@
module Mongo
class PoolManager

attr_reader :connection, :seeds, :arbiters, :primary, :secondaries,
:primary_pool, :read_pool, :secondary_pools, :hosts, :nodes, :max_bson_size,
attr_reader :connection, :arbiters, :primary, :secondaries, :primary_pool,
:read_pool, :secondary_pools, :hosts, :nodes, :max_bson_size,
:tags_to_pools, :tag_map, :members

def initialize(connection, seeds)
# Create a new set of connection pools.
#
# The pool manager will by default use the original seed list passed
# to the connection objects, accessible via connection.seeds. In addition,
# the user may pass an additional list of seeds nodes discovered in real
# time. The union of these lists will be used when attempting to connect,
# with the newly-discovered nodes being used first.
def initialize(connection, seeds=[])
@connection = connection
@original_seeds = connection.seeds
@seeds = seeds
@previously_connected = false
@refresh_required = false
end

def inspect
"<Mongo::PoolManager:0x#{self.object_id.to_s(16)} @seeds=#{@seeds}>"
end

def connect
if @previously_connected
close
end
close if @previously_connected

initialize_data
members = connect_to_members
initialize_pools(members)
update_seed_list(members)
cache_discovered_seeds(members)
set_read_pool
set_tag_mappings

Expand All @@ -35,7 +40,7 @@ def connect
# We're healthy if all members are pingable and if the view
# of the replica set returned by isMaster is equivalent
# to our view. If any of these isn't the case,
# set @refresh_require to true, and return.
# set @refresh_required to true, and return.
def check_connection_health
begin
seed = get_valid_seed_node
Expand Down Expand Up @@ -101,6 +106,12 @@ def close(opts={})
end
end

# The set of nodes that this class has discovered and
# successfully connected to.
def seeds
@seeds
end

private

def validate_existing_member(member)
Expand All @@ -124,6 +135,7 @@ def validate_existing_member(member)
end

def initialize_data
@seeds = []
@primary = nil
@primary_pool = nil
@read_pool = nil
Expand All @@ -134,6 +146,7 @@ def initialize_data
@members = Set.new
@tags_to_pools = {}
@tag_map = {}
@refresh_required = false
end

# Connect to each member of the replica set
Expand Down Expand Up @@ -255,7 +268,7 @@ def nearby_pool_from_set(pool_set)
#
# If we don't get a response, raise an exception.
def get_valid_seed_node
@seeds.each do |seed|
seed_list.each do |seed|
node = Mongo::Node.new(self.connection, seed)
if !node.connect
next
Expand All @@ -270,9 +283,12 @@ def get_valid_seed_node
"#{@seeds.map {|s| "#{s[0]}:#{s[1]}" }.join(', ')}"
end

def update_seed_list(members)
current_members = members.map { |n| n.host_port }
@seeds = (current_members + @seeds).uniq
def seed_list
@seeds | @original_seeds
end

def cache_discovered_seeds(members)
@seeds = members.map { |n| n.host_port }
end

end
Expand Down

0 comments on commit c25b1f1

Please sign in to comment.